2014-07-09 3 views
0

Я пытаюсь предложить пользователю ввести несколько номеров и, когда пользователь вводит строку, программа вычисляет сумму этих чисел. Я с трудом, потому что я хочу, чтобы сохранить программу как можно проще, не создавая другие переменные для хранения строк и т.д.Ввод различных типов (в C)

int menu(int choice){ 
    int total = 0, values = 0; 
    char *string = (char*) &values; 
    switch(choice){ 
    case 1: printf("Enter your values separated by a whitespace: "); 
     while(string != "compute") { 
     scanf("%d",&values); 
     total = total + values; 
     } 
    } 
    return total; 
} 

Я хочу, чтобы пользователь мог ввести стольких чисел, как он/она хочет (очевидно, в пределах ограничения памяти), поэтому я должен постоянно предвидеть int (или другое «число»), так что самый эффективный способ также предвидеть строку?

Я знаю, что следующая строка немного отрывочна, но почему именно, если я хочу, чтобы переменная «строка» обрабатывала «значения» как тип строки/символа? char *string = (char*) &values;

+2

Это не то, как вы сравниваете строки. 'man strcmp' –

+0

' string' указывает на тип 'int', и он никогда не будет содержать фактическую строку независимо от того, какой пользователь вводит' scanf'. Кроме того, это не так, как вы тестируете строки в C. Выполняя 'string! =" Compute "', вы фактически сравниваете указатели. – Havenard

+0

Чтобы это было просто, я предлагаю вам использовать вход 0 в качестве метки для завершения цикла. – Havenard

ответ

0

Когда вы пишете, как этот

int total = 0, values = 0; 
char *string = (char*) &values; 

Вы установите строку указатель, чтобы указать на целое значение values так, если пользователь вводит значение, которое больше, чем sizeof(values) т.е. SizeOf (INT), программа сбой.

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

char string[128] = {0};

зсапЕ может быть использован для ввода, но безопаснее использовать fgets(), чтобы свести к минимуму риск переполнения буфера:

fgets(string, sizeof(string), stdin);

Если вам нужно сохранить отдельные введенные значения, объявите массив целых чисел, например

int values[100];

, когда пользователь вводит что-то проверить содержание «строки» и посмотреть, если он содержит Compute - это может быть достаточно проверить первый символ - например, if (string[0] == 'c') еще преобразовать строку в целое и поместить его в массив значений:

values[i++] = atoi(string);

EDIT:

Как McNabb отметил fgets() добавляет \ п к строке, если вы хотите сравните всю строку, которую вы должны учитывать, например

if (!strncmp("compute", string, strlen("compute")) 
{...} 
+0

Было бы неплохо также упомянуть проблему '\ n' с' fgets', так как наивное приложение 'strcmp (string," compute ")' здесь не работает. –

+0

Да, хотя в этом случае он может просто проверить первый символ строки и atoi игнорировать \ n, но true, если будет больше ключевых слов, начинающихся с одной буквы. –

+0

Что такое «переполнение буфера» в этой ситуации? Вы уже объявили выделенный буфер, используя строку char [128] = {0}. Вы имеете в виду, если вход превышает 128 байтов? – fibono

0

Наиболее эффективным методом было бы прочитать в строке (используйте fgets()), а затем попытаться решить, что это такое. Если это целое число, вы можете использовать atoi или strtol для его преобразования. Если это поплавок, вы можете использовать strtod. В противном случае вы можете проанализировать строку, как хотите.

Таким образом, вы будете в конечном итоге с чем-то вроде этого:

char str[15]; 
long sum = 0, val; 
char* ptr; 
while (1) 
{ 
    fgets(str, 15, stdin); 
    if (0 == strcmp(str, "compute")) 
    { 
     printf("sum: %d\n", sum); 
     break; 
    } 
    val = strtol(str, &ptr, 10); 
    // error-check here. 
    sum += val; 
} 

Другой, более простой вариант, может быть читать целые числа (с помощью scanf, как в коде выше) до конца из-файла, а затем распечатать сумму. Этот подход имеет некоторые ограничения: вам нужно предоставить свой вход через какой-то канал с определенным EOF, и вы не сможете получить больше ввода после окончания списка целых чисел.Используйте определенное значение (например, 0) в качестве часового, как предположил Хэвенд, не имеет этих недостатков, но не позволяет указывать значение часового пояса в вашем списке чисел.

0

Чтобы прочитать строку, вам необходимо выделить для нее некоторое пространство. Вы не можете прочитать его в целое число.

Для поддержки чтения ввода, который может быть целым или строковым, вы должны прочитать строку; и затем вы можете попытаться преобразовать строку в целое.

Например:

char buffer[50]; 
scanf("%49s", buffer); 

if (0 == strcmp(buffer, "compute")) 
    return 0; // they typed "compute" 

if (0 == sscanf(buffer, "%d", &number)) 
    break;  // they typed something that was not a number 

total += number; 
0

Не уверен, почему вы пытаетесь сравнивать строки в этой точке. Если вы просто хотите прочитать целые числа, разделенные пробелами, до тех пор, пока не будет введено нецелое значение, пусть scanf сделает для вас работу:

int menu(int choice){ 
    int total = 0; 
    int value; 
    switch(choice){ 
    case 1: printf("Enter your values separated by a whitespace: "); 
     while(scanf("%d",&value) > 0) { 
     total += value; 
     } 
    } 
    /* Here, use scanf to get the first non-integer value entered */ 
    return total; 
} 
Смежные вопросы