2016-03-17 2 views
0

Вот моя программа для прочтения всех букв, введенных со стандартного ввода. Но некоторые результаты очень странные. Например, если ввод «lorem ipsum», а выход будет «LOREM IPSUMS?». Если ввод представляет собой один символ, такой как «m», выход будет «MZ # X?» , "S?" и "Z # X?" не должны быть здесь, но они присоединяются к выходу.Странный выход программы C с использованием функции toupper

Почему это происходит?

#include <stdio.h> 
#include <ctype.h> 

int main(void){ 
     char input; 
     char upper[100]; 
     int count = 0; 

     while((input = getchar())){ 
       if(input == '\n') 
         break; 
       if(input >= 'a' && input <= 'z') 
         input = toupper(input); 
       *(upper + count) = input; 
       count++; 
     } 

     printf("%s\n", upper); 

     return 0; 
} 
+5

Вы не нуль-прекратить вашу строку. – user2357112

+0

Строка в C нуждается в конечном маркере для правильной печати. – tofro

+1

Также стоит отметить ['getchar()'] (http://en.cppreference.com/w/c/io/getchar) возвращает EOF, ну, конец файла (включая ввод терминала, если это делается). Следовательно, без новой строки (например, перенаправления из файла с одной строкой, не связанной с новой строкой, или с кем-либо, нажимающей ctrlz/d на клавиатуре терминала), это будет работать навсегда. Не знаете, насколько суровым будет этот судья, но вы можете это исправить. – WhozCraig

ответ

0

Вы можете установить все элементы в массиве, чтобы быть 0 (ASCII NUL), потому что мы не имеем ни малейшего понятия, что находится в upper массиве.

#include <stdio.h> 
#include <ctype.h> 
#include <string.h> 

int main(void){ 
    char input; 
    char upper[100]; 
    int count = 0; 

    memset(upper, 0, 100); 

    while((input = getchar())){ 
      if(input == '\n') 
        break; 
      if(input >= 'a' && input <= 'z') 
        input = toupper(input); 
      *(upper + count) = input; 
      count++; 
    } 

    printf("%s\n", upper); 

    return 0; 
} 

Если вы не знаете, что делает memset, вы можете сделать это с помощью цикла for.

#include <stdio.h> 
#include <ctype.h> 
#include <string.h> 

int main(void){ 
    char input; 
    char upper[100]; 
    int count = 0; 

    for (int i = 0; i < 100; i++) { 
     upper[i] = 0; 
    } 

    while((input = getchar())){ 
      if(input == '\n') 
        break; 
      if(input >= 'a' && input <= 'z') 
        input = toupper(input); 
      *(upper + count) = input; 
      count++; 
    } 

    printf("%s\n", upper); 

    return 0; 
} 
+0

Is ** count ** фактически используемый или необходимый? –

+2

Есть ли какая-то причина * не * использовать 'upper [count] = 0;' после while-loop вместо того, чтобы взорвать область памяти с помощью nullchar, когда требуется только * one *, * и вы уже знаете, где он принадлежит * ? – WhozCraig

+0

OP использует счетчик для возврата к массиву 'upper'. – Warden

2

Ваш код работает для меня. Единственное, но это ожидается, вы получите мусор после строки, потому что ваш массив символов имеет длину 100. Вы должны положить 0 в конце строки, чтобы сообщить printf, что ваша строка заканчивается там. положить

*(upper + count) = 0; 

перед тем принтf.

+0

Спасибо, короткий, но чистый –

1

Ваш код имеет некоторые проблемы:

  • Нулевая терминатор не добавил в конце строки.
  • Нет никакой проверки индекса за пределами выделенного массива.
  • Пользователь может прерывать ввод без новой строки, создавая цикл программы навсегда.
  • getchar возвращает int.

Вы можете попробовать это исправить:

#include <stdio.h> 
#include <ctype.h> 

const int MAX_CHAR = 101; 

int main() { 
    int input; 
    char upper[MAX_CHAR]; 
    int count = 0; 

    while(count < MAX_CHAR - 1) { 
     input = getchar(); 
     if (input == EOF || input == '\n' || input == '\r') 
      break; 
     if (input >= 'a' && input <= 'z') 
      input = toupper(input); 
     upper[count] = input; 
     count++; 
    } 
    // add the null terminator 
    upper[count] = '\0'; 

    printf("%s\n", upper); 

    return 0; 
} 
+0

Спасибо. Действительно полезно! –