2012-02-21 7 views
2

У меня есть функция, которая принимает имя файла (string), и я хочу иметь массив имен файлов (строк), чтобы проверить, было ли передано имя файла taht в массиве и если не добавить его в него. Вот что я получил до сих пор.Проверка строки в массиве строк в C

bool read_file(char * filename, bool warnings){ 
    //Check to see if filename is in array files 
    static char * files[MAXFILES]; 
    static int counter = 0; 
    for(int i=0;i<counter;i++){ 
    if(strcmp(filename,files[i]) == 0){ 
     fprintf(stdout, "Error\n"); 
     return 0; 
    } 
    else{ 
     files[counter]=filename; 
     counter++; 
    } 
    } 
    FILE * fp = fopen(filename,"r"); 
    if(fp == NULL){ 
    if(warnings){ 
     fprintf(stderr, "Can't open the file %s\n",filename); 
     return 0; 
    } 
    else{ 
     return 0; 
    } 
    } 
    else{ 
    fclose(fp); 
    fp = NULL; 
    return 1; 
    } 
} 

По какой-то причине он не будет добавлять имена файлов в файлы [] любая помощь будет воспринята.

+0

Цикл 'for' никогда не вводится, вы инициализируете' counter' '' 0' и используете 'i Naveen

+0

Почему «counter» и 'files' должны быть статическими? – Lundin

ответ

1

Взгляните на первый раз через петлю (когда i == 0 и counter == 0):

static int counter = 0; 
for(int i = 0; i < counter; i++) { 
    // this never runs 
} 

i < counter всегда ложно, потому что counter увеличивается в теле для цикла.

Вам нужно будет переосмыслить свою логику. Эта функция делает много вещей. Может быть что-то вроде этого Infront цикла поможет:

if (counter == 0) { 
    // first time in the function, just add the filename 
    files[counter]=filename; 
    counter++; 
} 
else { 
    for (int i = 0; i < counter; i++) { 
     ... 
    } 
} 

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

+0

+1 для разделения функции - когда первый комментарий в функции, похоже, не совпадает с именем функции, вероятно, подходящее время для ее разбиения :) –

+0

Специальный корпус первой итерации не очень опрятен и аккуратно. Но я согласен с предложением разделить функцию на более мелкие части. A +1 и a -1 оставляет сетку без изменений. –

+0

@JonathanLeffler - Да, основная проблема заключается в том, что область действия слишком велика (и это действительно хочет быть классом). Специальная оболочка переменной 'counter' является быстрым взломом, чтобы дать время для правильного рефакторинга: D – Seth

0

изменить свой цикл в

for (i=0;i<=counter;i++) 
+0

Нет; это иногда, но только очень редко, хороший способ написать цикл в C. Цикл 'for (i = 0; i

1

Посмотрите на статьи этого цикла else :

for(int i=0;i<counter;i++){ 
    if(strcmp(filename,files[i]) == 0){ 
     fprintf(stdout, "Error\n"); 
     return 0; 
    } 
    else{ 
     files[counter]=filename; 
     counter++; 
    } 
    } 

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

for (int i = 0; i < counter; i++) 
{ 
    if (strcmp(filename, files[i]) == 0) 
    { 
     fprintf(stdout, "Duplicate file %s found at %d\n", filename, i); 
     return 0; 
    } 
} 
files[counter++] = filename; 

Обратите внимание на лучшее сообщение об ошибке, чем просто «Ошибка». Вам нужно будет знать, что пошло не так, потому что это не единственное место в программе, где могут быть ошибки. Вы можете обсудить, полезно ли это число; имя, безусловно, есть, но вам может помочь и номер индекса.

1

Ваш else неуместен. Это:

for(int i=0;i<counter;i++){ 
    if(strcmp(filename,files[i]) == 0){ 
     fprintf(stdout, "Error\n"); 
     return 0; 
    } 
    else{ 
     files[counter]=filename; 
     counter++; 
    } 
} 

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

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

for(int i=0;i<counter;i++){ 
    if(strcmp(filename,files[i]) == 0){ 
    fprintf(stdout, "Error\n"); 
    return 0; 
    } 
} 
files[counter]=filename; 
counter++; 

Ключ в том, что return 0 перенаправляет поток из вашей функции, а не п-то еще. Вы знаете, что до тех пор, пока цикл завершается, и вы все еще в функции, что имя файла еще не существует.

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