【问题标题】:Passing substring in C在 C 中传递子字符串
【发布时间】:2017-04-06 07:57:43
【问题描述】:

我昨晚一直在调试这段小代码。我有两个数据文本文件,都包含 18000 个字符。我想将这 18000 个拆分为两个子字符串,每个子字符串 100 个字符,这样可以进行 180 次迭代。

棘手的是,在前 180 次迭代中,两个子字符串的大小都很好。 18次迭代后,子串的大小为0。

两个文件均已正确打开。我可以打印它们等等。我试图以我能想到的所有可能的方式分配子字符串,但到目前为止找不到解决方案。

int main(int argc, char const *argv[]) { 

    //Ive loaded two files into two strings buff1 and buff2 both size of 18000 chars
    //It works fine with small data example, I dunno why but eventually I have work with much more bigger data set
    //Id like to divide them into 100 char long pieces and do some stuff with that 

    char *substrA;      //substring for buff1
    char *substrB;      //substring for buff2

    substrA = malloc((wlen+1)*sizeof(char));        //word length wlen=100
    substrA = malloc((wlen+1)*sizeof(char));

    for (int i= 0; i <numOfSubProblems; ++i){   //numOfSubProblems = 18000/100

        strncpy(substrA, buff1+i*wlen, wlen);
        strncpy(substrB, buff2+i*wlen, wlen);
        substrA[wlen] = '\0';
        substrA[wlen] = '\0';

        int lenA = strlen(substrA);
        int lenB = strlen(substrB);
        printf("STRA a STR B: %d %d \n",lenA,lenB);

        DoSomething(substrA,substrB,i);  //some parser and other functionality
    }
    return 0;
}

【问题讨论】:

  • subAsubB 声明在哪里?
  • strndup()代替malloc()+strncpy()怎么样?
  • 那么:有什么问题?

标签: c string substring


【解决方案1】:

strncpy 不会以空值结尾的目标字符串。所以你必须这样做

strncpy(subA, buff1+i*wlen, wlen);
subA[wlen] = '\0';
strncpy(subB, buff2+i*wlen, wlen);
subB[wlen] = '\0';

否则你不能使用strlen,并且你在这样做的时候会访问它们后面的缓冲区。

【讨论】:

  • 天哪,我真是个白痴,感谢解决了尺寸问题,但在第 18 个相同的问题之后,这些迭代仍然存在问题
  • strncpy 很好地终止了目标字符串除非它不适合目标数组。由于目标数组保证足够长,因此也可以使用strcpy 或传递wlen + 1。但是这里memcpy会更合适。
  • 它不会终止字符串,如果它是第一个len字符的一部分,它会复制'\0'(好的,结果基本相同)
  • @JerrySmith 我知道 buff1 和 buff2 有 18000 个字符,但是 buff1 和 buff2 中的字符串长度是多少?
  • @KarstenKoop 并且由于源是长度 > wlen 的字符串,因此它不会复制 NUL 字符。 QED。
【解决方案2】:

使用snprintf

您可能不会处理格式化字符串,但至少它是一个健全的 API。在确定子问题的数量时也要确保四舍五入:

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

#define PROBSIZE 18002

int main (int argc, char **argv) {
    char input[PROBSIZE];

    for (size_t i = 0; i < PROBSIZE; ++i) {
        input[i] = 'A' + (i % 10);
    }

    const size_t wlen = 10;
    char *subA = malloc (wlen + 1);
    if (!subA) {
        return EXIT_FAILURE;
    }

    for (int i = 0; i < (PROBSIZE + wlen - 1) / wlen; ++i) {
        /* If there's no error, guarantees `wlen` characters copied */
        int err = snprintf(subA, wlen + 1, "%s", input + i * wlen);

        if (err < 0) {
            fprintf(stderr, "snprintf encountered an error\n");
            return EXIT_FAILURE;
        }

        /* In absence of errors, we expect that the return value is
         * always >= wlen + 1, except the last iteration.
         */
        assert(err >= wlen + 1 || i == ((PROBSIZE + wlen - 1) / wlen) - 1);

        printf("%s\n", subA);
    }

    return EXIT_SUCCESS;
}

【讨论】:

    猜你喜欢
    • 2012-11-04
    • 2021-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-07
    • 1970-01-01
    • 2011-10-08
    • 2021-07-04
    相关资源
    最近更新 更多