Неправильное чтение файла в C - PullRequest
0 голосов
/ 02 октября 2018

Я занимаюсь программированием сокетов для больничной канализации.Я пытаюсь прочитать текстовый файл, подобный этому

1   Kavi    card    0   0   0
2   Anparasanesan   gene    0   0   0
3   Thilak  card    0   0   0
4   Akilanesan  immu    0   0   0
5   Aravinthanesan  derm    0   0   0
6   Akalya  derm    0   0   0
7   Vishvapriya derm    0   0   0
8   Kavinga immu    0   0   0
9   Anjalie andr    0   0   0
10  Tom andr    0   0   0

, но когда я читаю этот файл, он дает мне вывод:

enter image description here

1   Kavi    cardgenecardimmudermdermdermimmuandrandr
2   Anparasanesan   genecardimmudermdermdermimmuandrandr
3   Thilak  cardimmudermdermdermimmuandrandr
4   Akilanesan  immudermdermdermimmuandrandr
5   Aravinthanesan  dermdermdermimmuandrandr
6   Akalya  dermdermimmuandrandr
7   Vishvapriya dermimmuandrandr
8   Kavinga immuandrandr
9   Anjalie andrandr
10  Tom andr

Вот мой сегмент кода

char line[MAXCHAR];
        int x = 0;
            while (fgets(line, sizeof(line), fp)){ 
            sscanf(line,"%d\t%s\t%s\t%d\t%d\t%d",&dno,&dname,&dspl,&ti1,&ti2,&ti3);

            id[x]=dno;
            strncpy(name[x], dname, 50);
            strncpy(spl[x], dspl, 4);
            times[x][0]=ti1;
            times[x][1]=ti2;
            times[x][2]=ti3;

            x++;
            }

        int z=0;
        for(z=0;z<10;z++)
        {
            snprintf(line, sizeof(line),"%d\t%s\t%s\n",id[z],name[z],spl[z]);
            n = strlen(line);
            Writen(sockfd,line,n);
        }

1 Ответ

0 голосов
/ 02 октября 2018

Давайте рассмотрим одну из проблем.

зло strncpy

Код использует strncpy с магическим числом 4. Это не гарантирует, что spl[x] является строкой , поскольку у символов может отсутствовать конечный нулевой символ .

        strncpy(spl[x], dspl, 4);  // Avoid code like this

Более поздний код пытается напечатать string с "%s" и spl[z] и получает "cardgene ...", а не ожидаемую "карточку".Если spl[z] не является строкой, результатом будет неопределенное поведение (UB) - может произойти что угодно.

        // Alternative: could limit output with
        snprintf(line, sizeof(line),"%.*s\n",(int) (sizeof spl[z]), spl[z]);

Как исправить?

Не используйте sscanf(line,"%s",&dspl);, поскольку в нем отсутствует ограничение ширины, или неизвестно, что dspl примерно такого же размера, как line.Я ожидаю

char dspl[4+1];
sscanf(line,"%4s", dspl);

Лучше убедиться, что исходной строки и массива назначения достаточно, чем использовать strncpy() без тестов.

char spl[X_N][4+1];
char dspl[sizeof spl[0]];

// strncpy(spl[x], dspl, 4);
strcpy(spl[x], dspl);

Другие исправления включают в себя уверенность в sscanf()завершено, как ожидалось.Простой подход использует " %n" для записи смещения сканирования, если оно зашло так далеко, а затем ищет лишний мусор.Ненужное "\t" удалено.

// Insure  dname is at least 50+1, dspl is 4+1 or as big as the line
char dname[sizeof line];
char dspl[sizeof line];

// sscanf(line,"%d\t%s\t%s\t%d\t%d\t%d",&dno,&dname,&dspl,&ti1,&ti2,&ti3);
int n = 0;
sscanf(line,"%d%50s%4s%d%d%d %n",&dno,dname,dspl,&ti1,&ti2,&ti3, &n);
if (n==0 || line[n]) {
  puts("Bad Input");  // Handle bad input in some fashion
  exit(RETURN_FAILURE);
}
...