【问题标题】:removing spaces from a string in an array of strings从字符串数组中的字符串中删除空格
【发布时间】:2019-05-21 22:27:38
【问题描述】:

我目前正在从事一个从输入文件中读取字符串并将它们存储到数组中的项目。 当它存储到数组中时,我想删除空格,以便我可以将数组中的字符串与数组 stringcards 进行比较,并检查输入文件中的所有卡片是否都在那里。

但我目前被困在存储没有数组空间的新字符串并将它们打印出来。 它打印出第一个字符串REDA,但之后我得到一个分段错误。

如果有人能给我任何提示,告诉我如何将卡片数组中的字符串与常量数组进行比较并检查所有卡片是否都在数组中,我将不胜感激。

我希望这是正确的方法。

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

const char * stringcard[] = { "REDA","RED2"
                              "RED3"
                              "RED4"
                              "RED5"
                              "RED6"
                              "RED7"
                              "RED8"
                              "RED9"
                              "RED10"
                              "REDJ"
                              "REDQ"
                              "REDK"
                            };

int main (int argc, char **argv) {

    char *reds[13];
    char * cardarray[13];

    int i;

    FILE *file = argc > 1 ? fopen (argv[1], "r") : stdin;
    if (file == NULL)
        return 1;
    if(argc!=2) {
        printf("[ERR]");
        return 0;
    }

    for (i =0; i < 13; i++) {

        reds[i] = malloc( 8);
        fgets(reds[i], 8, file);

    }

    int i2 = 0;
    for (i =0; i < 13; i++) {

        printf ("%s", reds[i]);

    }

    for(i= 0; i<13; i++) {
        char *p = strtok (reds[i], " ");


        while (p != NULL)
        {
            cardarray[i2++] = p;
            p = strtok (NULL, " ");
        }
    }

    for (i =0; i < 13; i++) {

        printf ("%s", cardarray[i]);

    }


    return 0;
}

输入文件:

RED A
RED 2
RED 3
RED 4
RED 5
RED 6
RED 7
RED 8
RED 9
RED 10
RED J
RED Q
RED K

【问题讨论】:

  • 提示:不要使用“魔法”数字。这是一种非常糟糕和危险的做法。 13 是什么? malloc(sizeof(char) * (4 + 1) 中的 4 + 1 是什么?使用常量。
  • 13 是数组的大小,(4+1) 是最大字符串长度 4 + null 终止符@Jabberwocky
  • @xing 应该是reds[i] = malloc(sizeof(char) * (7 + 1))
  • @momonosuke 是的,我知道,但这是一种危险的做法。当您的卡片数量从 13 变为 15 时(无论出于何种原因),您需要将代码中的 13 更改为 15。使用常量并更改一次值。

标签: c arrays string file dynamic


【解决方案1】:

只需删除不需要的字符。这里有两个功能:

第一个算法要快得多。第二种比较慢但是容易理解

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

char *removechar(char *str, int ch)
{
    char *cptr = str, *readptr = str;

    while(*readptr)
    {
        if(*readptr == ch)
        {
            readptr++;
        }
        else
        {
            *cptr++ = *readptr++;
        }
    }
    *cptr = 0;
    return str;
}

char *removechar(char *str, int ch)
{
    char *cpos = str;

    while((cpos = strchr(cpos, ch)))
    {
        strcpy(cpos, cpos + 1);
    }
    return str;
}

【讨论】:

    【解决方案2】:

    至少有2个问题:

    首先:在这个循环中,您将i 增加两次,最终导致缓冲区溢出。

    for (i = 0; i < 13; i++) {
        char *p = strtok(reds[i], " ");    
    
        while (p != NULL)
        {
          if (i >= 13)           // debug code
          {                      // debug code
            printf("Bummer\n");  // debug code
            exit(1);             // debug code
          }                      // debug code
          cardarray[i++] = p;
          p = strtok(NULL, " ");
        }
      }
    

    其次:你没有在这里分配足够的内存:

    reds[i] = malloc(sizeof(char) * (4 + 1));   // you allocate space for 5 chars
    fgets(reds[i], 13, file);                   // and here you tell fgets that
                                                // your buffer has a length of 13 chars...
    

    但很可能还有更多错误。

    【讨论】:

    • 我更改了代码,但现在检测到错误堆栈粉碎
    • 堆栈粉碎意味着您很可能遇到索引越界问题。在 C 中未检查索引,越界访问数组会导致未定义的行为,这可能(或可能不会)表现为“堆栈粉碎”。检查您的索引,必要时添加调试代码。
    猜你喜欢
    • 2011-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-20
    相关资源
    最近更新 更多