2013-12-17 4 views
0

У меня проблема с кодом на C. Проблема состоит в том, что он не распознает допустимый ввод внутри цикла do ... while.C Код, идущий прямо к операторам «else» ...

int stp; 

do { 

    printf("\nPlease enter the packet data (maximum of 50 numbers): "); 
    while(getchar()!='\n'); 

    scanf("%s", dataTest); 

    if(dataTest == '\n') 
     scanf("%s", dataTest); 

    if(dataTest==1) { 

     length = strlen(dataTest); 

     if(length < 50) { 

      for(i=0;i<=length && stp!=1;i++) { 

       if ((dataTest[i] >= '0' && dataTest[i] <= '9') || (dataTest[i] == 0)) { 

        valid=1; 
        win_linux(); 

       } else { 

        printf("\nData must contain only numbers, '%c' is not a number. Please try again. \n", dataTest[i]); 
        stp=1; 
        valid=0; 

       } 

      } 

     } else { 

      valid = 0; 
      while(getchar()!='\n'); 
      printf("\nData should have no more than 50 numbers, you have entered %i",length); 

     } 

    } else { 

     printf("\nNot valid data, numeric only. Please try again"); 
     while(getchar()!='\n'); 
     valid=0; 

    } 

} while(valid!=1); 

Обратите внимание, что dataTest представляет собой массив из 50 char с.

Например, если я ввожу 1 (действительный вход) для сканирования е он идет прямо к заявлению еще «не достоверные данные, числовые только. Пожалуйста, повторите попытку»

Любые идеи?

Спасибо, ребята, заранее.

+0

Какой тип dataTest? Сначала вы пытаетесь сохранить в нем строку (подразумевая char *), тогда вы пытаетесь сравнить ее с символом (подразумевая char, который разбивает scanf), затем вы пытаетесь сравнить его с 1, что является int. – LinearZoetrope

+0

dataTest - символ. Условие «if (dataTest == 1)», как предполагается, является тестированием, - все данные являются числовыми. любые идеи, как я мог это сделать в инструкции if? – Charlieabee

+0

Подождите, я читал ваши другие комментарии. Вы уверены, что dataType имеет тип char, а не char *? – LinearZoetrope

ответ

1

if(dataTest==1) никогда не будет правдой, потому что вы делаете scanf("%s",...). dataTest - это строка, а не числовая 1. Если вы введете 1, это будет строка ("1"), а не номер (1).

Редактировать обратиться комментарии: @Charlieabee: Вы говорите, «Когда я ввести любой номер по одной цифре это вызывает ошибку, говоря" числовые данные только.»Правильно, потому что для любого числа более чем 1 цифра, это не точно равно «1». Ваш код не проверяет, является ли dataTest числовым; он проверяет, является ли это точно равным «1». Чтобы проверить, является ли каждый символ числом, вам нужно перебрать всю строку и убедиться, что каждый символ находится между «0» и «9».

Проще всего сделать то, что вы пытаетесь сделать, это scanf("%d", &intvar), где intvar имеет тип int. Тогда вам не придется беспокоиться о проверке строк вообще.

Но вы говорите, что пытаетесь получить массив из 50 символов. В этом случае у вас нет другого выбора, кроме как сделать scanf("%d %d %d %d ...", &intvar1, $intvar2, ... &intvar50); (на самом деле печатать все 50 %d и $intvarX) или выполнять синтаксический анализ строк. Но как бы то ни было, ваш код обречен, потому что вы сравниваете весь вход со строкой "1".

+0

, так что мне нужно изменить, чтобы, чтобы вход был полностью числовым? – Charlieabee

+0

Попробуйте 'if (atoi (dataTest) == 1)' –

+0

Это не сработало – Charlieabee

0

Эта линия:

if (dataTest==1) { 

просит «это строка dataTest по адресу 1?», И так как это не так, это не удастся. То, что вы, вероятно, хотите знать, является ли или нет строка номер 1. Есть несколько способов, если сделать это:

if (0 == strcmp("1", dataTest)) { 
. . . 

или

if (1 == strtol(dataTest, NULL, 10)) { 
. . . 
+0

Что я пытаюсь сделать, если (dataTest == 1) проверяет, что ввод является числовым. Не то, что dataTest представляет один. – Charlieabee

+0

Этот тест не будет проверять, что ввод является числовым; он будет проверять, что это точно 1. –

+0

C не имеет встроенных функций для тестирования целой строки числовой. Вы должны вызывать 'isdigit()' для всех своих символов. –

0

Я установил ее.

Я изменил

if(dataTest == 1) { 

в

if(dataTest >= 0) { 

Это сделало программу поток правильно. Спасибо за вашу помощь.

+0

dataTest ВСЕГДА будет> = 0. Это указатель на массив символов в стеке, единственными возможными значениями являются 0 (aka NULL) или действительный числовой адрес, который является целым числом без знака больше нуля. И, фактически, поскольку он находится в стеке, он никогда не будет NULL. – LinearZoetrope

+0

Извините, если это описание слишком техническое. То, что вы утверждаете, случайно щекочет некоторые низкоуровневые идиосинкразии C. В любом случае, если это заставляет вашу программу работать правильно, решение состоит в том, чтобы избавиться от этого оператора if и связанного с ним else. Код будет эквивалентен коду с (если dataTest> = 0) – LinearZoetrope

0

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

Поскольку dataTest является char [50] (и, таким образом, в char*), то утверждение if(dataTest == 1) спрашивает, если точный адрес памяти, который указывает на dataTest равен 1. Тот факт, что это иногда кажется, работает это случайно. Предлагаемое исправление от аскетиста об изменении его на if(dataTest >= 0) говорит. На большинство архитектуры, указатели всегда> = 0, причем 0 эквивалентно NULL. Таким образом, исправление OP эффективно удаляет оператор if и связанный с ним else.

Таким образом, решение становится

int stp; 

do { 

    printf("\nPlease enter the packet data (maximum of 50 numbers): "); 
    while(getchar()!='\n'); 

    scanf("%s", dataTest); 

    if(dataTest == '\n') 
     scanf("%s", dataTest); 

    length = strlen(dataTest); 

    if(length < 50) { 

     for(i=0;i<=length && stp!=1;i++) { 

      if ((dataTest[i] >= '0' && dataTest[i] <= '9') || (dataTest[i] == 0)) { 

       valid=1; 
       win_linux(); 

      } else { 

       printf("\nData must contain only numbers, '%c' is not a number. Please try again. \n", dataTest[i]); 
       stp=1; 
       valid=0; 

      } 

     } 

    } else { 

     valid = 0; 
     while(getchar()!='\n'); 
     printf("\nData should have no more than 50 numbers, you have entered %i",length); 

    } 

} while(valid!=1); 

Однако, следует отметить, что это сравнение указателя также аннулирует несколько других линий, таких как if(dataTest == '\n'), которая проверяет, если адрес dataTest указывает, случается, в точности равна к числовому значению символа новой строки (почти наверняка false). Таким образом, эта строка также может быть удалена.

Есть также несколько тонких ошибок. Например, scanf переполняет dataTest и повреждает память, если введено 50 или более символов.

Остальная часть кода искателя действительна C I/O, хотя и немного нечиста. Указанные изменения должны заставить его работать должным образом, но я бы предложил его очистить. Я предлагаю следующую C-программу, которая должна более или менее делать то, что хочет OP.

#include <stdio.h> 
#include <strings.h> 

int main(void) { 

    // Needs to be size 51 to allow for 50 chars 
    char dataTest[51]; 

    int valid = 0; 
    do { 
     while(getchar()!='\n'); // Flush stdin 
     printf("Please enter the packet data (max of 50 numbers): "); 

     // Scanf returns the number of arguments filled 
     // %50s says we want to read UP TO 50 chars before we hit whitespace 
     int successful = scanf("%50s", dataTest); 
     if(!successful) { 
       valid = 0; 
       continue; // If we didn't read right, try again 
     } 

     int length = strlen(dataTest); 
     if(length == 0) { 
       valid = 0; 
       continue; // If we only had whitespace, assume invalid 
     } 

     int i; 
     for(i = 0; i < length; i++) { 
      if(dataTest[i] >= '0' && dataTest[i] <= '9') { 
       valid = 1; 
       win_linux(); // this was in the original code by the OP 
      } else { 
       valid = 0; 
       break; // Takes the place of the stp variable 
      } 
     } 
    } while(!valid); 

    printf("%s\n", dataTest); 
} 
Смежные вопросы