【问题标题】:String wouldn't print itself in C字符串不会在 C 中打印自己
【发布时间】:2015-01-14 18:56:47
【问题描述】:

我正在尝试用 strtok 格式化一个 ASCII-Art 风格的字符串。当我尝试通过我的 IDE 运行我的程序时,它实际上是在打印我的十六进制字符串,所以我不必弄乱其中的所有反斜杠。但是,当我尝试在控制台(Ubuntu)中运行它时,它不会返回任何东西。

#include <sys/ioctl.h>
#include <stdio.h>
#include <string.h>

char pacmanText[] = { 0x20, 0x5f, 0x5f, 0x5f, 0x5f, 0x20, 0x20, 0x20, 0x20, 0x20, 
                      0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
                      0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
                      0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0d, 
                      0x0a, 0x7c, 0x20, 0x20, 0x5f, 0x20, 0x5c, 0x20, 0x5f, 0x5f, 
                      0x20, 0x5f, 0x20, 0x20, 0x5f, 0x5f, 0x5f, 0x20, 0x5f, 0x20, 
                      0x5f, 0x5f, 0x20, 0x5f, 0x5f, 0x5f, 0x20, 0x20, 0x20, 0x5f, 
                      0x5f, 0x20, 0x5f, 0x20, 0x5f, 0x20, 0x5f, 0x5f, 0x20, 0x20, 
                      0x0d, 0x0a, 0x7c, 0x20, 0x7c, 0x5f, 0x29, 0x20, 0x2f, 0x20, 
                      0x5f, 0x60, 0x20, 0x7c, 0x2f, 0x20, 0x5f, 0x5f, 0x7c, 0x20, 
                      0x27, 0x5f, 0x20, 0x60, 0x20, 0x5f, 0x20, 0x5c, 0x20, 0x2f, 
                      0x20, 0x5f, 0x60, 0x20, 0x7c, 0x20, 0x27, 0x5f, 0x20, 0x5c, 
                      0x20, 0x0d, 0x0a, 0x7c, 0x20, 0x20, 0x5f, 0x5f, 0x2f, 0x20, 
                      0x28, 0x5f, 0x7c, 0x20, 0x7c, 0x20, 0x28, 0x5f, 0x5f, 0x7c, 
                      0x20, 0x7c, 0x20, 0x7c, 0x20, 0x7c, 0x20, 0x7c, 0x20, 0x7c, 
                      0x20, 0x28, 0x5f, 0x7c, 0x20, 0x7c, 0x20, 0x7c, 0x20, 0x7c, 
                      0x20, 0x7c, 0x0d, 0x0a, 0x7c, 0x5f, 0x7c, 0x20, 0x20, 0x20, 
                      0x5c, 0x5f, 0x5f, 0x2c, 0x5f, 0x7c, 0x5c, 0x5f, 0x5f, 0x5f, 
                      0x7c, 0x5f, 0x7c, 0x20, 0x7c, 0x5f, 0x7c, 0x20, 0x7c, 0x5f, 
                      0x7c, 0x5c, 0x5f, 0x5f, 0x2c, 0x5f, 0x7c, 0x5f, 0x7c, 0x20, 
                      0x7c, 0x5f, 0x7c, 0x0d, 0x0a
}; 

int main() 
{ 
    struct winsize w; 
    ioctl(0, TIOCGWINSZ, &w); 

    char *pch = NULL; 

    pch = strtok(pacmanText, "\n"); 
    while (pch != NULL) 
    { 
        printf("%s", pch); 
        fflush(stdout); 

        pch = strtok(NULL, "\n"); 

    } 
    return 0; 
}

那么谁能告诉我为什么它不打印那个字符串?

【问题讨论】:

    标签: c string hex ascii-art


    【解决方案1】:

    问题:

    1. 由于iharob talks about 的原因,您需要在pacmanText 的末尾添加一个空终止字符。
    2. strtok() 将修改字符串,以便将分隔符替换为 '\0'。因此,您永远不会在整个程序中打印换行符。

    让我们修复这些错误:

    #include <stdio.h>
    #include <string.h>
    
    char pacmanText[] = {
        0x20, 0x5f, 0x5f, 0x5f, 0x5f, 0x20, 0x20, 0x20, 0x20, 0x20, 
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0d, 
        0x0a, 0x7c, 0x20, 0x20, 0x5f, 0x20, 0x5c, 0x20, 0x5f, 0x5f, 
        0x20, 0x5f, 0x20, 0x20, 0x5f, 0x5f, 0x5f, 0x20, 0x5f, 0x20, 
        0x5f, 0x5f, 0x20, 0x5f, 0x5f, 0x5f, 0x20, 0x20, 0x20, 0x5f, 
        0x5f, 0x20, 0x5f, 0x20, 0x5f, 0x20, 0x5f, 0x5f, 0x20, 0x20, 
        0x0d, 0x0a, 0x7c, 0x20, 0x7c, 0x5f, 0x29, 0x20, 0x2f, 0x20, 
        0x5f, 0x60, 0x20, 0x7c, 0x2f, 0x20, 0x5f, 0x5f, 0x7c, 0x20, 
        0x27, 0x5f, 0x20, 0x60, 0x20, 0x5f, 0x20, 0x5c, 0x20, 0x2f, 
        0x20, 0x5f, 0x60, 0x20, 0x7c, 0x20, 0x27, 0x5f, 0x20, 0x5c, 
        0x20, 0x0d, 0x0a, 0x7c, 0x20, 0x20, 0x5f, 0x5f, 0x2f, 0x20, 
        0x28, 0x5f, 0x7c, 0x20, 0x7c, 0x20, 0x28, 0x5f, 0x5f, 0x7c, 
        0x20, 0x7c, 0x20, 0x7c, 0x20, 0x7c, 0x20, 0x7c, 0x20, 0x7c, 
        0x20, 0x28, 0x5f, 0x7c, 0x20, 0x7c, 0x20, 0x7c, 0x20, 0x7c, 
        0x20, 0x7c, 0x0d, 0x0a, 0x7c, 0x5f, 0x7c, 0x20, 0x20, 0x20, 
        0x5c, 0x5f, 0x5f, 0x2c, 0x5f, 0x7c, 0x5c, 0x5f, 0x5f, 0x5f, 
        0x7c, 0x5f, 0x7c, 0x20, 0x7c, 0x5f, 0x7c, 0x20, 0x7c, 0x5f, 
        0x7c, 0x5c, 0x5f, 0x5f, 0x2c, 0x5f, 0x7c, 0x5f, 0x7c, 0x20, 
        0x7c, 0x5f, 0x7c, 0x0d, 0x0a, 0x00
    }; 
    
    int main() { 
        char *pch = strtok(pacmanText, "\n"); 
        while (pch != NULL) { 
            printf("%s\n", pch); 
            pch = strtok(NULL, "\n"); 
        } 
    }
    

    哪些输出:

    [1:08pm][wlynch@watermelon /tmp] ./foo
     ____                                  
    |  _ \ __ _  ___ _ __ ___   __ _ _ __  
    | |_) / _` |/ __| '_ ` _ \ / _` | '_ \ 
    |  __/ (_| | (__| | | | | | (_| | | | |
    |_|   \__,_|\___|_| |_| |_|\__,_|_| |_|
    

    【讨论】:

    • 这回答了这个问题,我只是希望 OP 解释一下strtok()
    • @iharob 我在你的帖子中回答了为什么我需要 strtok!
    • @iPh1ps99 我已经读过,并更新了我的答案。这是有道理的,尽管您可以将数组声明为二维并将每一行拆分为一个数组。
    • @iharob 是的,你是对的,但这会在每一个字符串上投入更多的精力。它不只是其中包含 pacman 文本的那个 :)
    【解决方案2】:

    您的字符串中没有'\0' 终止符,只需在数组末尾添加一个元素0x00,而且您的strtok() 正在正确拆分行,问题是您错过了'\n' 字符在行尾,所以只需更改它

    printf("%s", pch);
    

    printf("%s\n", pch);
    

    但是,这样做没有意义。你可以使用printf("%s", pacmanText);

    所以根本问题是strtok() 它用'\0' 替换分隔符所以当你这样做时

    printf("%s", pch);
    

    您没有打印分隔符。

    【讨论】:

    • 这实际上并没有改变任何东西,但感谢您的回答
    • @iPh1ps99 它可能不会改变任何东西,但是将数组原样传递给strtok 是未定义的行为。
    • @iPh1ps99 除了末尾之外,我在数组中看不到任何'\n' 字符,那么strtok 的意义何在?是不是数据不全?
    • 我刚刚,用了printf(),效果很好,你为什么用strtok(),能解释一下吗?
    • 好吧,我的问题是我实际上想将所有行分开存储在一个数组中,以便稍后我可以将整个输出的每行居中
    猜你喜欢
    • 1970-01-01
    • 2011-05-11
    • 2021-10-23
    • 1970-01-01
    • 2021-04-03
    • 2013-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多