如何在不知道字符串和字符大小的情况下动态地在C中创建字符串数组?

时间:2017-05-06 19:01:02

标签: c arrays string

我已尝试过所有内容,而且我的代码对我来说看起来非常好(如果它不起作用,显然不是这样。)

我试图从一些文本中读取用逗号分隔的单词列表,每个单词将是一个字符串数组的元素。我不知道会有多少元素或多长时间。

for循环是盛大的,因为我计算之前有多少个字符。主要问题是分配内存,有时我得到"分段错误:11"当我运行它(因为它编译宏)时,有时当我读取项目时它会得到类似的东西:

  

P 25 adios(null)heyya

什么时候给我这样的东西:

  

hola adios bye heyya

我想我正在访问内存,我不应该这样做。无论如何,这里是代码:

// We allocate memory for one string
variables = (char**)calloc(1, sizeof(char*));
variables[0] = (char*)calloc(100, sizeof(char));

if (variables == NULL) {
    return NULL;
}

// Now we start looking for the variables
for (int i = comma_pos+1; i < *(second_pos + pos); i++) {
    deleteSpaces(string, &i);
    // If the character is not a comma, we copy the character
    if (*(string + i) != ',') {
        *(variables[stringnum] + j) = *(string + i);
        j++;
    } else {
        // If the character is a comma, we have to allocate more memory for a new string
        *(variables[stringnum] + j) = '\0';
        stringnum++;
        j = 0;

        char **temp = variables;
        // We allocate more memory for a second array
        variables = realloc(variables, sizeof(char*) * stringnum);

        variables[stringnum] = (char*)calloc(100, sizeof(char));


        // If we cannot allocate more memory then get out
        if (variables == NULL) {
            return temp;
        }
    } // end else
} // end for

*(variables[stringnum] + j) = '\0';

2 个答案:

答案 0 :(得分:1)

我不清楚我的代码有什么问题,但我根本不知道如何处理这个问题。

我首先要通过计算源字符串中的分隔符并添加一个分隔符来确定有多少个子字符串。这确实需要对字符串进行预扫描,但它可能比需要执行多个内存分配的任何替代方案便宜得多。

至于字符串本身的空间,如果您不需要保留列表的逗号分隔形式,那么您可以重新使用该空间。使用strtok()函数对其进行标记,并存储生成的指针。

如果你必须保留原始逗号分隔的字符串,那么我建议制作整个事物的副本,然后按照我之前的建议进行标记(并且你将知道已经计算分隔符的时间长度)。对于单个字符串,您不需要比原始逗号分隔的空格更多的空间。

如果您希望避免strtok(),那么手动实施相同的操作并不困难。

答案 1 :(得分:0)

你必须在两个方向分配,也许你已经分配了。

你需要分配深度,一个指针数组,然后对于该数组中的每个指针,需要为该行分配宽度。

    CREATE OR REPLACE TRIGGER uprava_prac_casu
    BEFORE
    UPDATE OF worked_hours
    ON Attendance_of_employee
    FOR EACH ROW
    BEGIN
    IF (:new.worked_hours>15) THEN :worked_hours:=15; END IF;

    IF (:new.worked_hours<3) THEN :worked_hours:=3; END IF;
    END;
    /


Trigger UPRAVA_PRAC_CASU compiled

Errors: check compiler log