2015-12-17 3 views
1

Я пишу код, в котором я хочу, чтобы он сканировал имя до тех пор, пока оно не достигнет ":", но каким-то образом он продолжает сканировать ":". Вот мой код:сканирование строки до ":"

char letter, StudentName[1][40]; 
int j=0; 
scanf("%c", &letter); 
while (letter != ":") 
{ 
StudentName[1][j] = letter; 
j++; 
scanf("%c", &letter); 
} 

также, хотя код работает, я получаю предупреждение говорит: «предупреждение C4047:„=!“:„INT“отличается уровнем косвенности от«гольца [2]»

+3

Изменить 'StudentName [1] [j] = letter;' -> 'StudentName [0] [j] = letter;' Примечание: после цикла добавьте 'StudentName [0] [j] = '\ 0' ; '. – chux

+0

, если будет только 1 'StudentName', то зачем делать его двухмерным массивом? – user3629249

+0

chux- почему я должен добавить '\ 0'? не добавляется автоматически? –

ответ

-1

Вы можете сделать это таким образом, вам не нужна переменная letter.or, если вы хотите использовать переменную букву, вы просто необходимо присвоить символ «:» для письма и сравнить его со значением StudentName

int i,j; 
for(i=0;i<2;i++){ 
for(j=0;j<40;j++){ 
if(StudentName[i][j]==':')}break; 
scanf("%c", &StudentName[i][j]);} 
+0

Это не позволяет много вещей: 1) 'for (i = 0; i <2; i ++) .. break. 'является ненужным циклом' for' и 2) не позволяет 'scanf ("% c ", & StudentName [i] [j]);' вызываться. 3) '{if (StudentName [i] [j] == ':')}' является синтаксической ошибкой 4) 'scanf()' result не проверен. – chux

3

Вы выполняете сравнение строк вместо сравнения символов по условию цикла while.

Что вы по существу задаете ((char *) letter == (char *) "String").

Две вещи:

One - Это не так, как вы делаете сравнение строк. (См .: strcmp).

Два - вы даже не хотите выполнять сравнение строк, вы хотите сделать сравнение символов, поэтому измените двойную кавычку в одинарной кавычки.

Кроме того, ваша строка даже не находится в стеке, она находится в секции только для чтения, так как она была назначена во время компиляции, поэтому никакой указатель на стек/кучу никогда не будет равным :).

Кроме того, когда вы выделяете массив с N индексов, максимальный индекс вы можете получить доступ без риска/ошибки ошибки сегментации нарушения доступа N-1, так что в вашем примере, я бы изменить линию :

StudentName[1][j] = letter; 

в

StudentName[0][j] = letter; 

А также, для надежности - рассмотреть вопрос о создании верхней границы количества ввода пользователь может вставить (то есть - другое сотрудничество к общему циклу, в котором ограничение ограничено не более чем символами sizeof (StudentName).)

1

Там нет оснований объявлять StudentName в символьном StudentName[1][40]. Просто объявить массив как:

char StudentName[40] = {0}; 

Обратите внимание выше, массив также инициализируется содержать все zero «с. Это хорошая привычка. Существует ряд причин, по которым рекомендуется использовать все переменные. Здесь инициализации к 0 вы заполнить массив символов (который вы, вероятно, будет использоваться в качестве строки) с NUL оконечного символов, так что в случае, если вы не в явном виде прекратить вашу строку, это делается для вас в силу вашей инициализации.

Далее при приеме ввода символов, (символ в то время), вы обычно хотите использовать getchar или fgetc, чтобы избежать ряда ошибок, присущих при использовании scanf семейства функций.Простая реализация с `GetChar показано ниже:

#include <stdio.h> 

int main (void) { 

    char StudentName[40] = {0}; /* char array */ 
    int letter = 0;    /* int value */ 
    size_t idx = 0;    /* array index */ 

    printf ("\nEnter StudentName (until ':'): "); /* always prompt */ 

    /* read input until ':' (or end-of-line or end-of-input) */ 
    while ((letter = getchar()) != ':' && letter != '\n' && letter != EOF) { 
     StudentName[idx++] = letter; 

     if (idx + 1 == 40) break; /* prevent writing beyond array */ 
    } 

    StudentName[idx] = 0; /* nul-terminate string */ 

    printf ("\nYou entered: %s\n\n", StudentName); 

    return 0; 
} 

примечание: вы хотите проверить для часовому характера ':', но вы должны также проверить наличие конца-строки (символ новой строки '\n') и конец ввода (EOF, обычно -1). Если вы передадите файл или другой блок памяти вашему коду, и вы не сможете проверить для новой строки и EOF, если на вашем входе нет ':', ваш код продолжит чтение за пределами вашего ввода. (до тех пор, пока не произойдет что-то плохое ...) Аналогично, вам нужно проверить количество символов, которые вы храните в своем массиве, не превышает 40 - 1 (чтобы оставить место для символа nul-terminating). Простая проверка индекса или проверка количества сохраненных символов - это все, что требуется.

Хотя вы можете использовать индексы массивов для заполнения массива символами, это одна из многих ситуаций, когда вам обычно нужно назначить указатель на начало массива, а затем просто использовать указатель для заполнения ваш массив. Это, по сути, «то, что подходит для наилучшей» ситуации, что означает, что ни один из них не является более правильным/неправильным, чем знаком другой, но знакомство с хождением указателя вниз по строке является основополагающим для обработки строк и символов в C. Ниже приведен пример использования указатель.

#include <stdio.h> 

int main (void) { 

    char StudentName[40] = {0}; /* char array */ 
    char *p = StudentName;  /* pointer  */ 
    int c = 0;     /* int value */ 

    printf ("\nEnter StudentName (until ':'): "); /* always prompt */ 

    /* read input until ':' (or end-of-line or end-of-input) */ 
    while ((c = getchar()) != ':' && c != '\n' && c != EOF) { 
     *p++ = c; 

     if (p - StudentName + 1 == 40) break; /* prevent writing beyond array */ 
    } 

    *p = 0; /* nul-terminate string */ 

    printf ("\nYou entered: %s\n\n", StudentName); 

    return 0; 
} 

Вкомпилировать

gcc -Wall -Wextra -O3 -o bin/studentname studentname.c 

(заменить -O3 оптимизацию с -g генерировать отладочные символы с gcc)

Пример использования

$ ./bin/studentname 

Enter StudentName (until ':'): John Q. Smith:Age 21:Weight 180 

You entered: John Q. Smith 

или перенаправление ввода в программу:

$ printf "John Q. Smith:Age 21:Weight 180\n" | ./bin/studentname2 

Enter StudentName (until ':'): 
You entered: John Q. Smith 

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

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

+0

Много хороших идей!Minor: 'idx + 1 == 40' ->' idx + 1 == sizeof (StudentName) ' – chux

+1

Вы меня там нашли, но' 40' был намерен усилить корреляцию 'StudentName [40]', но это будет гораздо более поддерживаемым с 'sizeof (StudentName)'. Если бы у меня были мои druthers, у нас бы были '#define MAXC 40',' char StudentName [MAXC] = {0}; 'и' sizeof (StudentName) '...':) ' –

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