【问题标题】:Truncating a string while storing it in an array in c在将字符串存储在c中的数组中时截断字符串
【发布时间】:2013-11-11 21:28:26
【问题描述】:

我正在尝试创建一个由 20 个字符串组成的数组,其中最多包含 17 个字符,这些字符串是从名为“words.dat”的文件中获取的。之后,程序应截断仅显示前 17 个字符的字符串,并完全忽略该字符串的其余部分。不过

我的问题是:我不太确定如何完成这项任务,谁能给我一些关于如何完成这项任务的见解?

这是我当前的代码:

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

    #define WORDS 20
    #define LENGTH 18

    char  function1(char[WORDS][LENGTH]);

int main( void )
{

    char word_array [WORDS] [LENGTH]; 

    function1(word_array);

    return ( 0 ) ;

}

char function1(char word_array[WORDS][LENGTH])
{
    FILE *wordsfile = fopen("words.dat", "r");
    int i = 0;

    if (wordsfile == NULL)
        printf("\nwords.dat was not properly opened.\n");
    else
    {
        for (i = 0; i < WORDS; i++)
        {
            fscanf(wordsfile, "%17s", word_array[i]);
            printf ("%s \n", word_array[i]);
        }
        fclose(wordsfile);
    }
    return (word_array[WORDS][LENGTH]);
}

words.dat 文件:

Ninja
 DragonsFury
  failninja
   dragonsrage
    leagueoflegendssurfgthyjnu
     white
      black
       red
        green
         yellow
          green
           leagueoflegendssughjkuj
            dragonsfury
             Sword
              sodas
               tiger
                snakes
                 Swords
                  Snakes
                   sage

样本输出:

blahblah@fang:~>a.out
Ninja 
DragonsFury 
failninja 
dragonsrage 
leagueoflegendssu 
rfgthyjnu 
white 
black 
red 
green 
yellow 
green 
leagueoflegendssu 
ghjkuj 
dragonsfury 
Sword 
sodas 
tiger 
snakes 
Swords 
blahblah@fang:~>

这个程序之后将完成的事情是:

在 function1 正常工作后,我将创建第二个函数名称“function2”,它将在整个数组中查找匹配“完全”匹配的单词对,包括 case 。之后我将创建第三个函数,该函数显示我之前创建的 words.dat 文件中的 20 个字符串以及匹配的单词。

【问题讨论】:

  • 可能有点幼稚,但您可以逐个字符地读取文件,查找空格并计算读取的字符数。
  • 输入文件的样本可以很好地解决您的问题,因为我怀疑您需要进行每行处理,而发布的代码当然不需要。
  • 用输入文件编辑了这个,谢谢。
  • 只是一个想法:fscanf(wordsfile, "%17s %*[^\n]\n", word_array[i])
  • 您应该使function1 无效并删除最后一个return。它当前返回一个超出范围的字符。

标签: c arrays string function


【解决方案1】:

在你的循环中改变

fscanf(wordsfile, "%17s", word_array[i]);

fscanf(wordsfile, "% 17s%*[^\n]\n", word_array[i]);

它的基本作用是:

  1. %17s,这很明显,最多读取 17 个字符并将其放入您的 word_array 中
  2. %*[^\n],这会读取所有不是 \n 的字符并删除它们 (*)
  3. \n 读取换行符

我通过在您的代码中替换这一行来测试它并且工作正常。

正如其他人所提到的,请查看您对 function1 的调用的返回值。它基本上是word_array[20][18],是数组限制的两倍。这是word_array 的第 21 个元素的第 19 个字符。而你一个都没有。如果这个函数不返回任何值,它的工作方式也是一样的。

【讨论】:

  • 我这样做了,但是单词出现乱序,并且一些不在文本文件中的字符出现在输出中。
  • @Nick 查看已编辑的行。仔细检查控制字符串中的空格。现在它就像一个魅力:)
  • 最后的 \n 实际上读取(并丢弃)所有空格。因此,如果您删除它,答案(和程序)会更好。虽然从文件中读取时,无论有没有它都可以正常工作。
  • @ChrisDodd 我不知道。是否有理由不将其视为常规(可打印)字符?如果我删除它,它不会在上次迭代后将换行符留在输入缓冲区中吗?
【解决方案2】:

有几点需要注意。首先,我建议您让function1 返回读取的字数,而不是word_array[WORDS][LENGTH] 的字符,它位于您无法访问的内存位置。所以把函数改成返回int

int function1(char word_array[WORDS][LENGTH])

为了处理文件可能包含少于WORDS 字的可能性,您需要知道fscanf 何时失败,以及何时退出循环。

if( 1 != fscanf(wordsfile, "%17s", word_array[i]) ) break;

要忽略超过 17 个字符的剩余单词,您可以一次读取一个,直到遇到空格字符或 EOF

int c;
do { c = fgetc(wordsFile); } while( c != EOF && !isspace(c) );

把它们放在一起:

int function1(char word_array[WORDS][LENGTH])
{
    FILE *wordsfile = fopen("words.dat", "r");
    int c, i = 0;

    if (wordsfile == NULL)
    {
        printf("\nwords.dat was not properly opened.\n");
    }
    else
    {
        for (i = 0; i < WORDS; i++)
        {
            if( 1 != fscanf(wordsfile, "%17s", word_array[i]) ) break;

            /* eat remaining characters of long words */
            do { c = fgetc(wordsFile); } while( c != EOF && !isspace(c) );
        }
        fclose(wordsfile);
    }

    /* Return the number of words read */
    return i;
}

【讨论】:

  • 谢谢,帮了大忙!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-08
  • 1970-01-01
  • 1970-01-01
  • 2017-09-06
  • 2015-04-29
  • 1970-01-01
相关资源
最近更新 更多