2016-06-22 4 views
0

У меня есть файл вроде этого:прочитать файл и сохранить в виде матрицы

1 100 
2 200 
3 300 
4 400 
1 

я хочу сохранить его в виде матрицы, и я хочу, чтобы сохранить значение NULL, если нет второго номера!

Я попытался написать программу, но она работает неправильно!

#include<stdio.h> 
int main() { 
int k=0 ,i,j , arr[100][100]; 
FILE *in= fopen("file.txt","r"); 
char line[1000]; 
while(fgets(line,1000,in) !=NULL) k++; 
fgets(line,1000,in); 
for (i=0;i<k;i++){ 
    for (j=0;j<2;j++){ 
     int tmp ; 
     fscanf(in ,"%d", &tmp) ; 
     arr[i][j] = tmp ; 
    } 
} 
fclose(in); 
return 0; } 
+2

Вы не можете _store_ макрос 'NULL' в целое число. И вы не должны хранить его значение в целом в целом. – Olaf

+0

вам нужно «перемотать». – BLUEPIXY

+0

и использовать 'int ** arr;' instaed из 'int arr [100] [100];' – BLUEPIXY

ответ

2

две основные проблемы:

Первое, что первый цикл будет читать все линии, даже один с одним номером на линии. Это означает, что одинокий вызов fgets ничего не сделает, и что еще более важно, что значение k будет неправильным.

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

Первая проблема может быть решена путем пропуска второго вызова fgets и уменьшения k на один.

Вторая проблема может быть решена путем вызова rewind после подсчета количества строк.

Также, когда вы действительно читаете цифры, вам не нужен внутренний цикл, просто выполните, например,

scanf("%d %d", &arr[i][0], &arr[i][1]); 

На самом деле, вам не нужен первый контур линии подсчета на всех, вы можете сделать все это в одном цикле, используя fgets и sscanf, а затем проверять возвращаемое значение sscanf. Таким образом, ваша программа может выглядеть примерно так:

#include <stdio.h> 

int main(void) 
{ 
    int values[100][2]; 
    FILE *input = fopen("file.txt", "r"); 
    size_t entries = 0; 

    if (input != NULL) 
    { 
     char buffer[40]; 
     while (fgets(buffer, sizeof(buffer), input) != NULL && entries < 100) 
     { 
      int res = sscanf(buffer, "%d %d", &values[entries][0], &values[entries][1]); 
      if (res <= 1 || res == EOF) 
      { 
       // Read the last line with only one number, or an error happened 
       values[entries][0] = 0; 
       values[entries][1] = 0; 
       break; 
      } 

      ++entries; 
     } 

     if (ferror(input)) 
     { 
      printf("Error reading file\n"); 
     } 

     fclose(input); 
    } 

    // All done, the number of "records" or "entries" is in the variable entries 

    // Example code: print the values 
    for (size_t i = 0; i < entries; ++i) 
     printf("Line %d: %d %d\n", i + 1, values[i][0], values[i][1]); 

    return 0; 
} 
+0

@ ÐiffëřëņtĞîRl Обновлен код для обработки 'sscanf', не возвращающего' 2' по-другому. Но вы должны уточнить, что вы подразумеваете под «записью 1 с помощью NULL». 'NULL' является указателем *** *** ***, вы не должны назначать его целочисленной переменной. И вы должны действительно попытаться немного подумать о себе, мне действительно не нравится писать ваш код для вас, это не заставит вас на самом деле * научиться * ничего, кроме копирования. –

+0

Я надеюсь получить выходную матрицу следующим образом: [1 100; 2 200; 3 300; 4 400; 1 NULL]; , но в любом случае я постараюсь сделать –

+0

Хороший ответ: второстепенный вопрос: зачем использовать 'if (res <= 1 || res == EOF)' vs 'if (res <= 1)' или 'if (res! = 2) 'или ...? Подчеркивается какая-то ясность? Примечание: предложите 'printf (" Line% zu:% d% d \ n ", ...' – chux

Смежные вопросы