2013-11-19 3 views
0

У меня есть эта программа. Я хочу вводить многословные строки в двухмерном массиве. Но вместо ввода цельной строки в первом массиве 2-D массива эта программа вводит первые три слова моей строки в первые три массива каждый (поскольку я определил число строк в моем двумерном массиве). Здесь пока программа:Как ввести многословную строку в C

int main() 
{ 
char title[50]; 
int track; 
int question_no; 

printf("\nHow many questions?\t"); 
scanf("%d",&question_no); 
track=0; 
char question[question_no][100]; 
while(track<=question_no) 
    { 
     printf("Question no %d is:",track+1); 
     scanf("%s",question[track]); 
     printf("Q %d.%s",track,question[track]); 
     track++; 
    } 
} 

Здесь «question_no» это не строк, я хочу, чтобы ввести в моем 2-D array- «вопрос». Но когда я ввожу первую строку, первые три слова строки вводятся в три массива 2-мерного массива. Он даже не просит меня вводить 2-ю или 3-ю строки.

Решение этой проблемы, как я считаю, должно быть трехмерным массивом. Потому что в этом случае 2-D массивы внутри самого внешнего массива будут печатать целую многословную строку (но и я тоже связан с длиной каждой строки). Если эта концепция 3-мерного массива может решить проблему, то есть ли и эффективный метод? Это лучше, быстрее и менее трудоемко, чем метод трехмерных массивов.

ответ

1

scanf("%s") сканирует строку до первой части пробела, которую она находит, поэтому она не подходит для ввода нескольких слов.

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

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

#define OK  0 
#define NO_INPUT 1 
#define TOO_LONG 2 
static int getLine (char *prmpt, char *buff, size_t sz) { 
    int ch, extra; 

    // Get line with buffer overrun protection. 
    if (prmpt != NULL) { 
     printf ("%s", prmpt); 
     fflush (stdout); 
    } 
    if (fgets (buff, sz, stdin) == NULL) 
     return NO_INPUT; 

    // If it was too long, there'll be no newline. In that case, we flush 
    // to end of line so that excess doesn't affect the next call. 
    if (buff[strlen(buff)-1] != '\n') { 
     extra = 0; 
     while (((ch = getchar()) != '\n') && (ch != EOF)) 
      extra = 1; 
     return (extra == 1) ? TOO_LONG : OK; 
    } 

    // Otherwise remove newline and give string back to caller. 
    buff[strlen(buff)-1] = '\0'; 
    return OK; 
} 

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

Программа испытаний можно увидеть ниже:

int main (void) { 
    int rc; 
    char buff[10] = ""; 

    while (1) { 
     rc = getLine ("\nWhat? ", buff, sizeof(buff)); 
     if (rc == NO_INPUT) { 
      // Extra NL since my system doesn't output that on EOF. 
      printf ("\nNo input\n"); 
      return 1; 
     } 

     if (rc == TOO_LONG) { 
      printf ("Input too long [%s]\n", buff); 
      continue; 
     } 

     if (strcmp (buff, "exit") == 0) 
      break; 
     printf ("OK [%s]\n", buff); 
    } 

    return 0; 
} 

И транскрипт следующим образом:

pax> ./testprog 

What? hello 
OK [hello] 

What? this is way too big for the input buffer 
Input too long [this is w] 

What? 
OK [] 

What? exit 

pax> _ 
+0

Я новичок, поэтому я не могу понять. Но я сохранил его в .pdf для будущего обучения. :) –

+0

Спасибо @paxdiablo Ты настоящий профессионал. Я сейчас учу вас от вас. –

0

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

+0

За исключением gets() никогда не следует использовать, поскольку он не имеет защиты переполнения буфера. Используйте fgets(), и все в порядке. – Daniel

+0

fgets(). , Хммм! Это было хорошее предложение @ Даниэль Спасибо! :) –

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