Napisanie swoich funkcji atoi, atof i strlen.

0

Witam

Mam takie zadanie

Napisz swoje wersje funkcji strlen, atoi oraz atof o następujących prototypach:

unsigned int my_strlen(const char tab[]);
int my_atoi(const char tab[]);
float my_atof(const char tab[]);

W przypadku kiedy konwersja nie jest możliwa, funkcje my_atoi i my_atof mają zwrócić wartość 0.

Napisz program, który pobierze od użytkownika ciąg znaków (nie więcej niż 15). Następnie korzystając z powyższych funkcji policzy i wypisze w oddzielnych liniach długość wprowadzonego ciągu, wynik jego konwersji na typ int i float (wartość typu float ma być wyświetlona z dokładnością 4 miejsc po przecinku).

Uwaga: W programie nie można korzystać z bibliotek stdlib i string oraz z funkcji z rodziny scanf (oprócz funkcji scanf).

Przykładowe wejście:

podaj liczbe: -81.15570695872059

Przykładowe wyjście:

15
-81
-81.1557

Przed rozpoczęciem pisania części main napisałem 3 funkcje, jednak przy wypisaniu main, zdałem sobie sprawę że nie jestem pewnym czy mogę tak wprowadzić dane, oraz czy moje i dostanie poprawną wartość, w trakcie kompilacji dostaje zawsze 0, możliwe że źle wychodzę z funkcji. Proszę o informacje o wczytywanie danych ewentualnie wskazówkę co poprawić w funkcjach, nie chce (na razie) gotowców

#include <stdio.h>

unsigned int my_strlen(const char tab[])
{
    int i = 0;
    do {
        if (tab[i] == '-' || tab[i] == ',' || (tab[i] >= '0' && tab[i] <= '9')) {
            i++;
        }
        else if (tab[i] == EOF) {
            break;
        }
        else {
            return 0;
        }
    } while (tab[i] != EOF);
    return i;
}

int my_atoi(const char tab[])
{
    int i = 0;
    do {

        if (tab[i] != ',') {
            printf("%c", tab[i]);
            i++;
        }
    } while (tab[i] != ',');
}
float my_atof(const char tab[])
{
    int i = 0;
    int k = 0;
    int n = 0;
    do {
        if (tab[i] != ',' && k == 0) {
            printf("%c", tab[i]);
            i++;
        }
        else {
            int k = 1;
            printf("%c", tab[i]);
        }

        if (tab[i] != ',' && k == 1) {
            printf("%c", tab[i]);
            i++;
            n++;
            if (n == 4) {
                return 0;
            }
        }

    } while (tab[i] != EOF);
    return 0;
}

int main(void)
{
    int i = 0;
    char tab[15];
    printf("podaj liczbe: ");
    scanf("%15[^\n]", tab);
    i = my_strlen(tab);
    if (i >= 15) {
        i = 15;
        printf("%i\n", i);
    }
    else
        printf("%i", i);
    return 0;
}

0

Ja bym po prostu otworzył pliki kompilatora z implementacją wymaganych funkcji i C+P do programu

1

To tak:

  • jako wymóg daj, że przekazana tablica będzie się kończyła bajtem 0
  • my_atoi nic nie robi, nawet się skompilować nie powinno bo nie zwracasz niczego.
  • my_atof też nic nie robi, bo zawsze zwracasz zero.

Przy takich założeniach aby stworzyć powyższe funkcje potrzebujesz:

  • my_strlen(): tworzysz zmienną counter, inicjujesz ją zerem, po czym inkementujesz ją w pętli sprawdzającej warunek, czy na danej pozycji nie jest wartość 0 (nie pomyl ze znakiem '0')
  • my_atoi(): wpierw szukasz końca łańcucha, możesz posłużyć się powyższą funkcją my_strlen(). Potem bierzesz od końca po jednej cyfrze, i tą znajdującą się na końcu zostawiasz bez zmian, następną mnożysz przez 10, kolejną przez 1010, czwartą przez 1010*10 itd., z uwzględnieniem przecinka; oczywiście tworzysz sobie przed tym zmienną result = 0 na której te operacje będziesz wykonywał
  • ny_atof(): najprostszą sztuczką chyba będzie wpierw znaleźć pozycję separatora dziesiętnego, przesunąć go o 4 miejsca w prawo dopisując w razie potrzeby zera, wysłać tak zmieniony string do my_atof(), a rezultat podzielić przez 10000 używając rzutowania.
1

podpowiem ci wiodącą dla strlen pętlę:


while(tab[i]!='\0')
  i++;


I nic więcej, żadnych udziwnień.

Konwersje literek do liczb (nie zrobiłęś nic merytorycznego) robi się:
a) przygotuj akumulator odpowiednio całkowitoliczbowy lub przecinkowy = 0;
b) zapamiętaj czy może jest minus
c) while not koniec mnóż akumulator*10 i dodawaj cyfrę.

d) opcja przecinkowa ma wykrycie przecinka i pewną pętlę, jest to generalnie w sieci
e) ewentualnie odwróć znak

Chciałbym Ci z wrócić uwagę, że źle analizujesz zadany temat, my_strlen jest nade wszystko jakimś tam klonem strlena, nic mu do znaków cyfrowych, literowych itd... przykład na liczbach cię zmylił.

0

Natomiast realizacja atoi nie wymaga znania długości liczby:

int atoi(char t[])
{
    int mul = 1;
    int ret = 0;
    if (t[0] == '-') {
        mul = -1;
        t += 1;
    }
    while (*t) {
        ret *= 10;
        ret += *t - '0';
        t += 1;
    }
    return ret;
}
6

Zacznij od pisanie testów:

int test_my_atoi()
{
    int failureCount = 0;

    static const struct AtoiTestData {
        const char *input;
        int expected;
    } atoiTestData[] = {
         { "", 0 },
         { "1", 1 },
         { "-1", -1 },
         { "2", 2 },
         ..... // wymyśl sam wiecej
    };
    const atoiTestDataCount = sizeof(atoiTestData) / sizeof(atoiTestData[0]);

    for (int i = 0; i < atoiTestDataCount; ++ i) {
         int result = my_atoi(atoiTestData[i].input);
         if (result != atoiTestData[i].expected) {
               ++failureCount;
               printf("test_my_atoi/%d FAILURE\nExpected: %d\nActual: %d\n", i, atoiTestData[i].expected, result);
         }
    }
    printf("test_my_atoi: %s!\n", failureCount == 0 ? "PASSED" : "FAILED");
    return failureCount;
}

wtedy szybko, bez naszej pomocy, będziesz wiedział: czy twój kod idzie w dobrym kierunku czy zbacza na manowce.

0

Doszedłem do takiej formy, jednak atoi oraz atof daje głupoty, przypuszczam że to może być błąd jeśli chodzi o typ danych :/, Czy można prosić o jakieś sprostowanie co poprawić?

#include <stdio.h>

unsigned int my_strlen(const char tab[])
{
	int i = 0;
	do
	{
		if (tab[i] == '-' || tab[i] == ',' || (tab[i] >= '0' && tab[i] <= '9'))
		{
			i++;
		}
		else if (tab[i] == 0)
		{
			break;
		}
		else
		{
			return 0;
		}
	} while (tab[i] != 0);
	return i;
}

int my_atoi(const char tab[])
{
	int i = 0;
	int j = 0;
	int mno = 1;
	do
	{
		
		if(tab[i]!=',')
		{
				i++;
		}
	}while (tab[i] != ',');


	if (tab[0] != '-')
	{
		for (int k = i; k >= 0; k--)
		{
			j = j + (k*mno);
			mno = mno * 10;
		} 
	}
	else
	{
		for (int k = i; k > 0; k--)
		{
			j = j+(k*mno);
			mno = mno * 10;
		}
		j = j * (-1);
	}

	return j;
}

float my_atof(const char tab[])
{
	int i = 0;
	int p = 0.1;
	int suma = 0;
	do
	{

		if (tab[i] != ',')
		{
			i++;
		}
	} while (tab[i] != ',');

	for (int j = i; j < i + 4; j++)
	{
		suma = suma + (j*p);
		p = p * 0.1;
	}
	

	return suma;
}

int main(void)
{
	float r = 0;
	int i = 0;
	int l = 0;
	char tab[15];
	printf("podaj liczbe: ");
	scanf("%15[^\n]", tab);
	i = my_strlen(tab);
	if (i > 15)
		i = 15;

	printf("%i\n", i);

	l = my_atoi(tab);
	
	printf("%i\n", l);

	r = my_atof(tab);

	r = l + r;

	printf("%.4f", r);
	getchar();
	getchar();
	getchar();

	return 0;
}

Funkcja my_strlen działa prawidłowo

0

kod jest strasznie barokowy, z wielkim nadmiarem.
Przechodząc do szczegółów

int p =0.1 
p = p*0.1


int suma
float return suma

to nie ma prawa działać.

while != ',' 

jest złym warunkiem. Zbuduj while nie while ! negatywny warunek, tylko while pozytywny

Chyba z dziesięć wątpliwych miejsc / błędów. Sugeruję nie ulepszać, a zaorać.

Dodaj do danych testowych dla float ciąg 12345 (bez niczego więcej). To jest też prawidłowa dana float.

1 użytkowników online, w tym zalogowanych: 0, gości: 1