如何将文本扫描到函数中的字符串中?

时间:2017-03-18 04:57:19

标签: c function scanf

所以我必须将文件中的文本扫描到数组中,但我只允许使用scanf()来实现这一点。在文件中,有22行,最长行为455个字符。当我编译时,我收到各种警告。我一直试图找到一个解决方案,但nothings似乎有助于我的警告和错误列表。

#include <stdio.h>
#include <stdlib.h>

#define NUM_ROWS 22
#define LENGTH_OF_LONGEST_LINE 455
void textInit(char array[]);

int main(void) {
   char patty [NUM_ROWS][LENGTH_OF_LONGEST_LINE];

   textInit(patty[NUM_ROWS][LENGTH_OF_LONGEST_LINE]);


   return 0;
}


void textInit(char array[]) {

   int x = 0;

   for (x = 0; x < 22; ++x) {
      scanf("%455s", array[x]);
   }
   return;
}

我收到的错误是:

StPat.c: In function âmainâ:
StPat.c:14:4: warning: passing argument 1 of âtextInitâ makes pointer from 
integer without a cast [enabled by default]
    textInit(patty[NUM_ROWS][LENGTH_OF_LONGEST_LINE]);
    ^
StPat.c:9:6: note: expected âchar *â but argument is of type âcharâ
     void textInit(char array[]);
     ^
StPat.c: In function âtextInitâ:
StPat.c:26:7: warning: format â%sâ expects argument of type âchar *â, but
argument 2 has type âintâ [-Wformat=]
       scanf("%455s", array[x]);

2 个答案:

答案 0 :(得分:1)

LENGTH_OF_LONGEST_LINE应为456,以便为\0终结符留出空间。

函数textInit()的主体需要一个2d数组,但函数签名只表示char的数组。您还应该将数组的维度传递给函数,而不是依赖于全局常量。

当你调用textInit()函数时,你试图传递char而不是2d数组(实际上,函数调用中的2d数组名称会衰减到指向数组的指针)。尝试访问超出范围。

最后,在textInit()函数中,避免使用幻数,就像在此函数的循环中一样。你应该使用size_t作为数组索引,因为它是一个无符号整数类型,保证保存任何数组索引。

以下是您的代码的修改版本:

#include <stdio.h>
#include <stdlib.h>

#define NUM_ROWS 22
#define LENGTH_OF_LONGEST_LINE 456

void textInit(char array[][LENGTH_OF_LONGEST_LINE], size_t rows, size_t cols);

int main(void)
{
   char patty [NUM_ROWS][LENGTH_OF_LONGEST_LINE];

   textInit(patty, NUM_ROWS, LENGTH_OF_LONGEST_LINE);

   return 0;
}


void textInit(char array[][LENGTH_OF_LONGEST_LINE], size_t rows, size_t cols)
{
    size_t x = 0;

   for (x = 0; x < rows; ++x) {
      scanf("%455s", array[x]);
   }

   return;
}

答案 1 :(得分:1)

除了Bowling先生的nul-byte捕获之外,您还可以使用fgets来获取输入。如果要初始化整个数组,可以传递指针数组以键入char LENGTH_OF_LONGEST_LINE 并立即初始化整个数组。例如:

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

enum { MAXROWS = 22, MAXLINE = 456 };

size_t textinit (char (*a)[MAXLINE], size_t rows, size_t cols);

int main(void) {

    size_t i, n;
    char patty [MAXROWS][MAXLINE] = {""};

    n = textinit (patty, MAXROWS, MAXLINE);

    for (i = 0; i < n; i++)
        printf (" string[%2zu] : %s\n", i, patty[i]);

    return 0;
}


size_t textinit (char (*a)[MAXLINE], size_t rows, size_t cols)
{
    size_t n = 0;

    while (n < rows && fgets (a[n], cols, stdin)) 
    {
        size_t len = strlen (a[n]); /* get lenght */
        if (a[n][len - 1] == '\n')  /* check for '\n' */
            a[n][--len] = 0;        /* overwrite with nul-byte */
        n++;
    }

    return n;   /* return number of strings read */
}

请注意,fgets读取并包含'\n',因此您可以通过获取每个字符串的长度来删除换行符,然后测试并覆盖'\n' nul-terminatedating 字符0(或等效的'\0')。

另请注意,如果您使用的是Windows,请使用size_t中的unsigned%2zu替换printf,只需%2u