2016-11-17 3 views
-1

У меня есть текстовый файл с 32 двоичными номерами, каждый из которых находится в отдельной строке и каждый номер имеет длину 8 символов. Я хочу сохранить их в массиве mem в виде строк.Обозначение символа новой строки

Сейчас этот код выглядит следующим образом:

char mem[32][9]; 
    char line[9]; 

    FILE *file_pointer; 
    file_pointer = fopen(filename, "r"); 

    if (file_pointer == NULL) { 
     printf("Failed to open file \"%s\"!", filename); 
    } else { 
     int i = 0; 
     while (fgets(line, sizeof line, file_pointer)) { 
      memcpy(mem[i], line, 8); 
      mem[i][8] = '\0'; 
      i++; 
     } 
    } 
    fclose(file_pointer); 

К сожалению, я все еще получаю символы новой строки в line, так что мой массив отображается неправильно.

Это моя консоль, когда я печать массива:

00  00110100 
01 

02  01111100 
03 

04  10011100 
05 

06  10010101 
etc... 

Мой код для печати массива:

for (i = 0; i < 32; i++) { 
    if (i >= 10) { 
     printf("%d", i); 
    } else { 
     printf("%c%d", '0', i); 
    } 
    printf("\t%s\n", mem[i]); 
} 

Я попытался также с помощью:

strtok(line, "\n"); 

line[strcspn(line, "\r\n")] = '\0'; 
+0

'тетсру (MEM [я], линия, 8);', что ожидаете увидеть, имеет ли 'строка' менее 8 символов? –

+0

Измените 'line [9]' на 'line [100]'. И измените 'memcpy' на' strncpy'. – user3386109

+1

'char line [9];' -> 'char line [10];': 8 + '\ n' +' \ 0' – BLUEPIXY

ответ

3

Некоторые примечания о вашем коде:

  • Вы должны сделать line дольше, поэтому fgets() может читать '\n' в line. В настоящее время он разбивает каждую строку на 8-байтовый фрагмент и пустую строку с символом новой строки.

  • Следует избегать цикла петли while за пределами конца массива.

Вот улучшенная версия

char mem[32][9] = { 0 }; 
    char line[80]; 

    FILE *file_pointer = fopen(filename, "r"); 

    if (file_pointer == NULL) { 
     fprintf(stderr, "Failed to open file \"%s\"!\n", filename); 
    } else { 
     int i = 0; 
     while (i < 32 && fgets(line, sizeof line, file_pointer)) { 
      strncat(mem[i], line, 8); 
      i++; 
     } 
     if (i < 32) { 
      fprintf(stderr, "Missing values in file \"%s\": found %d lines\n", 
        filename, i); 
     } 
     fclose(file_pointer); 
    } 

Можно также упростить код печати таким образом:

for (int i = 0; i < 32; i++) { 
     printf("%02d\t%s\n", i, mem[i]); 
    } 

Обратите внимание, что если вы уверены в формат файла, вы можете упростить код считывания таким образом:

char mem[32][9]; 
    char line[80]; 

    FILE *file_pointer = fopen(filename, "r"); 

    if (file_pointer == NULL) { 
     fprintf(stderr, "Failed to open file \"%s\"!\n", filename); 
    } else { 
     if (fread(mem, 9, 32, fp) != 32) { 
      fprintf(stderr, "Missing bytes in file %s\n", filename); 
     } else { 
      for (int i = 0; i < 32; i++) { 
       mem[i][8] = '\0'; 
      } 
     } 
     fclose(file_pointer); 
    } 

Вы также можете проверить, что строки в mem[] содержат ровно 8 шестнадцатеричных цифр с помощью простого цикла и с помощью функции isxdigit() из <ctype.h>:

  for (int i = 0; i < 32; i++) { 
       int j; 
       for (j = 0; j < 8; i++) { 
        if (!isxdigit((unsigned char)mem[i][j]) 
         break; 
       } 
       if (j != 8 || mem[i][8] != \n') { 
        fprintf("invalid data on line %d\n", i + 1); 
       } 
       mem[i][8] = '\0'; 
      } 
+1

Стоит ли показывать, что сообщения об ошибках должны быть напечатаны до стандартной ошибки? Кроме того, 'fclose()' должен находиться внутри блока 'else'; 'fclose()' разрешено (и обычно делает) сбой при передаче нулевого указателя. –

+0

@JonathanLeffler: хорошая точка. ответ обновлен. – chqrlie