Skocz do zawartości
Zamknięcie Forum PC LAB

Szanowny Użytkowniku,

Informujemy, że za 30 dni tj. 30 listopada 2024 r. serwis internetowy Forum PC LAB zostanie zamknięty.

Administrator Serwisu Forum PC LAB - Ringier Axel Springer Polska sp. z o.o. z siedzibą w Warszawie: wypowiada całość usług Serwisu Forum PC LAB z zachowaniem miesięcznego okresu wypowiedzenia.

Administrator Serwisu Forum PC LAB informuje, że:

  1. Z dniem 29 listopada 2024 r. zakończy się świadczenie wszystkich usług Serwisu Forum PC LAB. Ważną przyczyną uzasadniającą wypowiedzenie jest zamknięcie Serwisu Forum PC LAB
  2. Dotychczas zamowione przez Użytkownika usługi Serwisu Forum PC LAB będą świadczone w okresie wypowiedzenia tj. do dnia 29 listopada 2024 r.
  3. Po ogłoszeniu zamknięcia Serwisu Forum od dnia 30 października 2024 r. zakładanie nowych kont w serwisie Forum PC LAB nie będzie możliwe
  4. Wraz z zamknięciem Serwisu Forum PC LAB, tj. dnia 29 listopada 2024 r. nie będzie już dostępny katalog treści Forum PC LAB. Do tego czasu Użytkownicy Forum PC LAB mają dostęp do swoich treści w zakładce "Profil", gdzie mają możliwość ich skopiowania lub archiwizowania w formie screenshotów.
  5. Administrator danych osobowych Użytkowników - Ringier Axel Springer Polska sp. z o.o. z siedzibą w Warszawie zapewnia realizację praw podmiotów danych osobowych przez cały okres świadczenia usług Serwisu Forum PC LAB. Szczegółowe informacje znajdziesz w Polityce Prywatności

Administrator informuje, iż wraz z zamknięciem Serwisu Forum PC LAB, dane osobowe Użytkowników Serwisu Forum PC LAB zostaną trwale usunięte ze względu na brak podstawy ich dalszego przetwarzania. Proces trwałego usuwania danych z kopii zapasowych może przekroczyć termin zamknięcia Forum PC LAB o kilka miesięcy. Wyjątek może stanowić przetwarzanie danych użytkownika do czasu zakończenia toczących się postepowań.

Temat został przeniesiony do archiwum

Ten temat przebywa obecnie w archiwum. Dodawanie nowych odpowiedzi zostało zablokowane.

Matt91111

[Rozwiązany] [C] Odczytanie liczb z pliku

Rekomendowane odpowiedzi

Przeczytane znaki lądują w zmiennej "znaki", później odzielam je przy użyciu "strtok".

Problem pojawia się przy konwersji char do int przy użyciu atoi. Debuger wyrzuca segmentation fault.

//z funkcji przeczytaj_z_pliku
tablica[nTab] = atoi(kawalek);

 

Wiem, że są inne możliwości konwersji, ale mam kilka znaków które muszą być przekonwertowane.

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <stdbool.h>
#include <unistd.h>
#include <string.h>

#define LICZBA_EL_W_WIERSZU 5
#define RESET_TAB_INT(TAB) for(i=0; i<5; i++, TAB[i] = INT_MAX)
#define BREAK ;
#define MAX_LICZBA_ZNAKOW_W_PLIKU 512
#define MAX_LICZBA_ZNAKOW_W_LINI 40
#define MAX_LICZBA_LINI 10

//strukutra wiersz
struct Wiersz {
  int el[LICZBA_EL_W_WIERSZU];//tablica liczb
  int n;//jak duzo elementow zawiera tablica, moze byc niepelna
};

typedef struct Wiersz Wiersz;

//zmienne globalne
Wiersz* pWiersze;
int nWiersz;
int szWiersz;

//deklaracje funkcji
void wyswietl_wiersze();
bool dodaj_wiersz(int iLiczby[LICZBA_EL_W_WIERSZU]);
bool przeczytaj_z_pliku(const char*);
bool dodaj_do_tablicy(int);

int main()
{
  //inicjujemy wartosci potrzebne do dynamicznej alokacjii
  pWiersze = 0;//wskaznik na tablice
  nWiersz = 0;//ilosc elementow tablicy
  szWiersz = 0;//wielkosc tablicy
  pWiersze = malloc(szWiersz);//przydzielamy pamiec

  if(!przeczytaj_z_pliku("./tablice.txt"))
  {
     printf("blad podczas otwierania pliku! \n");
  }
  wyswietl_wiersze();

  return 0;
}

bool dodaj_wiersz(int iLiczby[LICZBA_EL_W_WIERSZU]) {
  szWiersz = szWiersz + sizeof(Wiersz);//ziekszamy rozmiar ktory bedzie potrzebny do przydzielenia nowej pamieci
  pWiersze = realloc(pWiersze, szWiersz);//przydzielamy nowa pamiec

  int temp[] = { INT_MAX, INT_MAX, INT_MAX, INT_MAX, INT_MAX };//definiujemy "pusta" tablice
  Wiersz wiersz = {temp, 0};//ustawiamy nowy wiersz jako "pusty"

  int i;

  wiersz.n = 0;
  for(i = 0; i < LICZBA_EL_W_WIERSZU; i++, wiersz.el[i] = iLiczby[i]) {} //przepisujemy liczby do wiersza
  for(i = 0; i < LICZBA_EL_W_WIERSZU; i++) {
     if(temp[i] != INT_MAX) //jezeli wartosc w tablicy jest rozna od "pustej"
        wiersz.n++;//zwiekszamy ilosc elementow w wierszu
  }

  if(pWiersze) {//jezeli operacja sie udala
     nWiersz++;//zwiekszamy liczbe elementow tablicy typu Wiersz
     pWiersze[nWiersz - 1] = wiersz;//ustawiamy nowy element
  }
}

bool przeczytaj_z_pliku(const char* sSciezkaDoPliku) {
  FILE* file;//wskaznik na plik
  char ch;//znak ktory bedziemy czytac

  int i;//licznik petli

  file=fopen(sSciezkaDoPliku, "r");//otwieramy plik

  if(file == NULL)
     return false;//blad otwarcia pliku

  char znaki[MAX_LICZBA_ZNAKOW_W_PLIKU];
  char linia[MAX_LICZBA_ZNAKOW_W_LINI];

  int linie = 0;
  while(!feof(file) && linie < MAX_LICZBA_LINI) {
     fgets(linia, MAX_LICZBA_ZNAKOW_W_LINI, file);
     linie++;

     strcat(znaki, linia);//dokladamy zawartosc lini do znakow
  }

  int tablica[LICZBA_EL_W_WIERSZU] = {INT_MAX, INT_MAX, INT_MAX, INT_MAX, INT_MAX};//"pusta" tablica
  int nTab = 0;

  const char separator[] = " ,\n";
  char kawalek = strtok(znaki, separator);

  while( kawalek != NULL ) {

     if(nTab == 4) {
        nTab = 0;
        dodaj_wiersz(tablica);
        RESET_TAB_INT(tablica);
     }

     tablica[nTab] = atoi(kawalek); // <-- Segmentation fault
     nTab++;

     kawalek = strtok(NULL, separator);
  }

  /*
  while(ch != EOF) { //sprawdzamy czy dotarlismy na koniec pliku
     ch=fgetc(file);//czytamy 1 znak

     if(isdigit() != 0) { //sprawdzamy czy znak jest liczba
        if(nTab == 4) { //kontrolujemy lementy wiersza
           nTab == 0; //liczymy od nowa
           dodaj_wiersz(tablica);//dodajemy wiersz z biezacymi elementami
           RESET_TAB_INT(tablica); //ustawiamy "pust¹" tablice
        }
        tablica[nTab] = (int)ch;
        nTab++;//inkrementujemy licznik dodanych liczb
     }
  }


  for(i = 0; i < tablica[LICZBA_EL_W_WIERSZU]; i++) { //iterujemy tablice
     if(tablica[i] != INT_MAX) { //jesli liczba jest rozna od przyjetej pustej wartosci dodajemy niepelny wiersz
        dodaj_wiersz(tablica);
        break;
     }
  }
  */
  return true;
}

void wyswietl_wiersze() {
  int i, j;
  for(i = 0; i < nWiersz; i++) {//iteracja wierszy
     for(j = 0; j < pWiersze[i].n ; j++) { //wyswietlamy tyle elementow ile zawiera wiersz
        printf("\t%d", pWiersze[i].el[j]);

        if(j == (pWiersze[i].n - 1) )//jezeli wyswietlamy ostatni element tablicy wstawiamy znak nowej lini
           printf("\n");
     }
  }
}


Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Kiedy zaczniesz wrzucać kod który nie pluje warningami?

 

Na pewno przeczytałeś co robi atoi?

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Tak w sumie to nie ogarniam w czym jest problem :kwasny: (po przeczytaniu dokumentacji) Przecież nic nie wychodzi poza zakres int więc w czym problem :E

 

atoi dostaje tylko kawalek tj "1 2 3 4 5" z tym że w for po kolei cyferki lecą jako pojedyncze, debuger pokazuje ze znaki zostały wczytane poprawnie.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Jaki zakres... panie, typy Ci się srogo potupały ;)

 

Deklaracja atoi:

int atoi (const char * str);

 

Twój kod:

char kawalek = strtok(znaki, separator);

(...)

tablica[nTab] = atoi(kawalek);

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Jaki zakres... panie, typy Ci się srogo potupały ;)

 

Deklaracja atoi:

 

 

Twój kod:

Troszkie mnie przykład zmylił :E

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

  • Ostatnio przeglądający   0 użytkowników

    Brak zarejestrowanych użytkowników przeglądających tę stronę.

×
×
  • Dodaj nową pozycję...