2017-02-22 47 views
-4

У меня есть входной файл, который толькоСтрока указатель массива в C передавая только один символ

Яблоко Banana груша и т.д. все на разных линиях

и мне нужно использовать цикл, чтобы перейти линию -by-line, присваивая каждой строке переменной, а затем передавая эту строку другим функциям. Я делаю это, используя fscanf (обязательно). В настоящее время я в мой основной()

char *name; 
for (i=0; i<=fileLength; i++) { 
    input(fp1, name) 
    printf("%s", &name); 
    // later would pass name elsewhere 
} 

и

void input(FILE *fp1, char name) { 
    fscanf(fp1, "%s", &name); 
    printf("%s", &name); 
} 

Если я бегу заявление PRINTF от входной функции, я получаю всю строку отлично. Если я запустил его из основного, я просто получил «А». Он не будет позже изменен на «B» при выполнении строки банана, хотя вывод printf в функции ввода корректно выводится. Что дает и как я могу получить имя var, напечатанное в моей main(), и позже сможет передать этот var?

+0

'голец name' ... хммм –

+0

' недействительным вход (FILE * FP1, символ * имя) { fscanf (FP1, "% s", имя) ; printf ("% s", имя); } 'для стартеров –

+0

' char * name' инициализируется, вам нужно выделить место для него. – RoadRunner

ответ

0

Ваш код имеет неопределенное поведение.

Вы не можете сохранить строку из более чем 0 символов в одном char (так как терминатор принимает один символ, в этом случае вы можете иметь 0 символов фактической строки).

Вы должны использовать массивы символов, чтобы освободить место:

void input(char *name, FILE *fp1) 
{ 
    if(fscanf(fp1, "%s", name) == 1) 
    printf("%s\n", name); 
} 

Затем вызовите его, как это, например:

char namebuffer[128]; 

input(namebuffer, fp1); 

Следует заметить, что я редактировал это использовать fscanf() так как это было требование, но это действительно плохое решение. Он не будет читать строку с пробелом в ней, поэтому типичное полное имя «firstname lastname» не будет правильно прочитано. Есть способы обойти это, но я не уверен, где рисовать линию здесь.

Также переполнение буфера может легко произойти здесь, так как нет защиты. Это можно добавить при сохранении fscanf(), но это немного раздражает.

+0

Может также хотеть использовать 'char * input ...' и иметь возможность возвращать успех/отказ ('NULL') вызывающему. (OP также отметил использование 'fscanf' в качестве требования - бедный парень) –

0

Вы используете инициализированный указатель char *name, что приводит к неопределенному поведению. Вы должны убедиться, что у name достаточно места, удерживая строки, которые вы читаете из файла. Вы можете просто создать VLA, например char name[n], который может содержать до n символов. Другим вариантом будет динамическое распределение name, но это может создать ненужные накладные расходы.

Вам также необходимо проверить возврат fscanf(), так как он возвращает количество отсканированных элементов. В вашем случае вы хотели бы прочитать одно слово за раз, пока EOF. Было бы лучше также использовать fgets(3) для чтения ввода, а не fscanf().

Вот небольшой пример:

#include <stdio.h> 
#include <stdlib.h> 

#define WORDSIZE 100 

/* function which reads one word */ 
int input(FILE *stream, char word[]) { 
    if (fscanf(stream, " %99s", word) != 1) { 
     return 0; 
    } 
    return 1; 
} 

int main(void) { 
    FILE *fptr; 

    /* array which holds words */ 
    char word[WORDSIZE]; 

    fptr = fopen("somewords.txt", "r"); 
    if (fptr == NULL) { 
     fprintf(stderr, "Cannot open file\n"); 
     exit(EXIT_FAILURE); 
    } 

    /* Keeps running loop until input() returns 0 */ 
    while (input(fptr, word)) { 
     printf("%s\n", word); 
    } 

    return 0; 
}