c - 尝试访问 C 中字符串数组的第一个字符时出现段错误

标签 c arrays string char character

p 类似于

[["test"], ["lest"]]

它打印 p[j] 意味着它打印“test”

char **p;
p = explode[i] = split(eachLineOfLsInArray[i]);
for(j=0;p[j];++j)
    puts(p[j]);

但在尝试打印 p[j][0] 时出现段错误,意味着尝试打印“t”

char **p;
p = explode[i] = split(eachLineOfLsInArray[i]);
for(j=0;p[j];++j)
    puts(p[j][0]);

编辑:

这是整个代码。 Lorem ipsum dolor sat amet,consectetur adipiscing elit。

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

char **split(const char *s);

int main (int argc, char *argv[]){
    char virtualLs[100];
    char eachLineOfLsInArray[100][100];
    scanf("%[^\t]", virtualLs);
    char *eachLineOfLs;
    eachLineOfLs = strtok(virtualLs, "\n");
    int loopCounterForStuffing;
    loopCounterForStuffing = 0;
    while (eachLineOfLs != NULL)
    {
        strcpy(eachLineOfLsInArray[loopCounterForStuffing], eachLineOfLs);
        eachLineOfLs = strtok(NULL, "\n");
        ++loopCounterForStuffing;
    }

    char **explode[sizeof(eachLineOfLsInArray)/sizeof(*eachLineOfLsInArray)];
    int i,j, n = sizeof(eachLineOfLsInArray)/sizeof(*eachLineOfLsInArray);
    int maximum = 0;
    int maximumindex = 0;
    int maximumname = 0;
    for(i=0;i < n; ++i){
        char **p;
        p = explode[i] = split(eachLineOfLsInArray[i]);
        for(j=0;p[j];++j)
        {
            putchar(p[j][0]);
            printf("%c", p[j][0]);
        }

    }
    return 0;
}

static int wordCount(const char *s){
    char prev = ' ';
    int wc = 0;
    while(*s){
        if(isspace(prev) && !isspace(*s)){
            ++wc;
        }
        prev = *s++;
    }
    return wc;
}

char **split(const char *s){
    int i, wc = wordCount(s);
    char *word, **result = calloc(wc+1, sizeof(char*));
    char *clone = strdup(s);//Note that you are copying a whole
    for(word=strtok(clone, " \t\n"); word; word=strtok(NULL, " \t\n")){
        result[i++] = word;//or strdup(word); and free(clone); before return
    }
    return result;
}

最佳答案

此代码在 split() 中初始化 i 并将打印循环限制为读取的数据(否则还包括一些调试 I/O,主要是为了显示其他调试技术)。

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

char **split(const char *s);

int main(void)
{
    char virtualLs[100];
    char eachLineOfLsInArray[100][100];
    scanf("%[^\t]", virtualLs);
    char *eachLineOfLs;
    eachLineOfLs = strtok(virtualLs, "\n");
    int loopCounterForStuffing;
    loopCounterForStuffing = 0;
    while (eachLineOfLs != NULL)
    {
        printf("each: <<%s>>\n", eachLineOfLs);
        strcpy(eachLineOfLsInArray[loopCounterForStuffing], eachLineOfLs);
        eachLineOfLs = strtok(NULL, "\n");
        ++loopCounterForStuffing;
    }
    printf("LoopC = %d\n", loopCounterForStuffing);

    char **explode[sizeof(eachLineOfLsInArray) / sizeof(*eachLineOfLsInArray)];
    int i, j, n = sizeof(eachLineOfLsInArray) / sizeof(*eachLineOfLsInArray);
    printf("n = %d\n", n);
    for (i = 0; i < loopCounterForStuffing; ++i)
    {
        char **p;
        p = explode[i] = split(eachLineOfLsInArray[i]);
        for (j = 0; p[j]; ++j)
        {
            putchar(p[j][0]);
            printf("%c", p[j][0]);
        }
        putchar('\n');
    }
    return 0;
}

static int wordCount(const char *s)
{
    char prev = ' ';
    int wc = 0;
    while (*s)
    {
        if (isspace(prev) && !isspace(*s))
        {
            ++wc;
        }
        prev = *s++;
    }
    return wc;
}

char **split(const char *s)
{
    int i = 0;
    int wc = wordCount(s) + 1;
    printf("Word count = %d\n", wc);
    char *word;
    char **result = calloc(wc + 1, sizeof(char *));
    char *clone = strdup(s);// Note that you are copying a whole
    for (word = strtok(clone, " \t\n"); word; word = strtok(NULL, " \t\n"))
    {
        printf("Word: <<%s>>\n", word);
        result[i++] = word;// or strdup(word); and free(clone); before return
    }
    result[i] = 0;
    return result;
}

示例输出:

$ ./split <<< "Lorem ipsum dolor sit amet, consectetur adipiscing elit."
each: <<Lorem ipsum dolor sit amet, consectetur adipiscing elit.>>
LoopC = 1
n = 100
Word count = 9
Word: <<Lorem>>
Word: <<ipsum>>
Word: <<dolor>>
Word: <<sit>>
Word: <<amet,>>
Word: <<consectetur>>
Word: <<adipiscing>>
Word: <<elit.>>
LLiiddssaaccaaee
$ 

输出是每个单词的第一个字符,在结束的行上打印两次。

关于c - 尝试访问 C 中字符串数组的第一个字符时出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26092209/

相关文章:

c - XC16 编译器 - 为 BTSTS(间接内存寻址)创建内存操作数的内联汇编约束

c++ - GMP:得到差异的绝对值?

javascript - 使用 math.random 随机排列数组

c - 数组中出现次数最少的数

python - 将 redis 哈希转换为 python 字典?

java - 如何从文件中逐行读入 JTextArea (GUI)?

c - 如果使用字符串不起作用

c++ - 从字符串加载 Gdk Pixbuf

Java - 像二维数组一样填充多维(二维)ArrayList

Python - 将浮点算术作为字符串