【问题标题】:Strings "concatenation" inside a 'for' block'for'块内的字符串“连接”
【发布时间】:2019-06-21 14:19:01
【问题描述】:

我正在尝试在 C 中实现某种“连接”以在一个字符串中使用几个值。

代码如下所示:

#include <stdio.h>

#define A "A"

int main() {

    char *textArray[] = {"a", "b", "c"};
    int intArray[] = {1, 2, 3};

    int n;
    // count intArray[] lengh
    // example taken from the https://www.sanfoundry.com/c-program-number-elements-array/
    n = sizeof(intArray)/sizeof(int);

    int i;
    char *concat;
    for (i=0; i<n; i++) {
        // check if values are accessible
        printf("TEST: Macro: %s, textArray's value: %s, intArray's value: %d\n", A, textArray[i], intArray[i]);

        // making concatenation here - this will work
        concat = "Macro: " A " textArray's value: '' intArray's value: ''";

        // this will NOT work
        // expected result == 'Macro: A textArray's value: a intArray's value: 1' etc
        // concat = "Macro: " A " textArray's value: " textArray[i] " intArray's value: " intArray[i];
        printf("%s\n", concat);
    }

    return 0;
}

此代码仅在使用 A 宏的值时可以正常工作:

$ ./array_test 
TEST: Macro: A, textArray's value: a, intArray's value: 1
Macro: A textArray's value: '' intArray's value: ''
TEST: Macro: A, textArray's value: b, intArray's value: 2
Macro: A textArray's value: '' intArray's value: ''
TEST: Macro: A, textArray's value: c, intArray's value: 3
Macro: A textArray's value: '' intArray's value: ''

但如果我尝试使用textArray[i],即:

...
// making concatenation here - this will work
// concat = "Macro: " A " textArray's value: '' intArray's value: ''";

// this will NOT work
// expected result == 'Macro: A textArray's value: a intArray's value: 1' etc
concat = "Macro: " A " textArray's value: " textArray[i] " intArray's value: " intArray[i];
printf("%s\n", concat);
...

编译时出错:

$ gcc array_test.c -o array_test
array_test.c: In function ‘main’:
array_test.c:26:53: error: expected ‘;’ before ‘textArray’
         concat = "Macro: " A " textArray's value: " textArray[i] " intArray's value: " intArray[i];

所以问题是:我在这里做错了什么以及实现目标的正确方法是什么?

UPD:最终目标是将一个字符串传递给像mysql_query() 这样的函数,例如mysql_query(conn, concat) 其中concat 将包含类似"INSERT INTO TableName VALUES('textValue', 'intValue')" 的值。

【问题讨论】:

  • 为什么不printf("Macro: %s %s: %d\n", A, textArray[i], intArray[i]);
  • @Someprogrammerdude 为我的目标添加了 UPD。
  • 或者sprintf,如果你想把它存储在一个变量中
  • 如果你需要一个字符串,那么snprintf代替?
  • 附带说明,如果您真的要将其传递给mysql_query,通常不要。请改用参数绑定。串联可能导致 SQL 注入攻击。

标签: c arrays string concatenation


【解决方案1】:

感谢@Some programmer dude 评论 - 我使用sprintf() 找到了解决方案。

所以我的代码(另一个,“原始”代码,具有相同的想法)现在看起来像:

...
    char *textArray[] = {"a", "b", "c"};
    int intArray[] = {1, 2, 3};

    int n;
    // count intArray[] lengh
    // example taken from the https://www.sanfoundry.com/c-program-number-elements-array/
    n = sizeof(intArray)/sizeof(int);

    int i;
    for (i=0; i<n; i++) {
        // best to check needed size for malloc() using sizeof()
        // saving a query string into the `buffer` var
        sprintf(buffer, "INSERT INTO %s VALUES(NULL, '%s', '%d')" , DB_TABLE, textArray[i], intArray[i]);
        // pass connection obj + query string to the `mysql_query()`
        mysqlexec(con, buffer);
    }
...

还有一个专用的mysqlexec() 函数:

void mysqlexec(MYSQL *con, char *query) {

    printf("Running query: %s\n", query);

    if (mysql_query(con, query)) {
      finish_with_error(con);
    }
}

现在一切正常:

$ ./get_id 
Running query: INSERT INTO ExampleTable VALUES(NULL, 'a', '1')
Running query: INSERT INTO ExampleTable VALUES(NULL, 'b', '2')
Running query: INSERT INTO ExampleTable VALUES(NULL, 'c', '3')
The last inserted row id is: 3

检查结果:

MariaDB [testdb]> select * from ExampleTable;
+----+---------+--------+
| Id | TextCol | IntCol |
+----+---------+--------+
|  1 | a       |      1 |
|  2 | b       |      2 |
|  3 | c       |      3 |
+----+---------+--------+

【讨论】:

    【解决方案2】:

    "string" "string1" "string2" 不是串联。它只是字符串文字的语法正确形式之一。

    【讨论】:

    • 嗯?源代码中的字符串文字由编译器连接成目标文件中的单个字符串文字。
    • @PaulOgilvie 内部编译器在做什么并不重要。不应使用该术语,因为它对许多人来说非常混乱 - 您应该在阅读本主题时注意到这一点
    【解决方案3】:

    textArray[i] 是运行时的,但您使用的字符串连接,即"string1" "string2" 仅在编译时有效,因为 编译器 连接这些字符串。

    使用textArray[i] 将需要编译器插入代码来评估itextArray[i] 中的字符或字符串,然后有代码来连接字符串。

    【讨论】:

      【解决方案4】:

      "Foo" MACRO "Bar" 其中MACRO"27" 在预处理器时展平为"Foo" "27" "Bar",然后由编译器进一步展平为"Foo27Bar"。您必须使用标准字符串 concat 函数将其他值合并为新字符串。

      【讨论】:

        猜你喜欢
        • 2020-02-24
        • 1970-01-01
        • 2022-06-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-12-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多