2

我曾在 Python 上工作过,我知道要将字符串连接为 --- 你可以简单地用字符“-”“乘”一个整数,所以在这种情况下,我们可以像 result=3*“-”一样简单地做到这一点. 我一直试图用 C 语言来做这件事。

如何在 C 中执行此操作,例如:

#include <stdio.h>
int main (void)
{

    int height=0;
    int n=0;
    char symbol='#';
    printf("Height: ");
    scanf("%d",&height);
    n=height+1;
    while (n>=2)
        {
        printf("symbol*n");
        n=n-1;
        }
    return 0;
}

所以它打印一个高度为 5 的倒金字塔:

#####
####
###
##
#

先感谢您!!

4

2 回答 2

2

没有内置的方法可以重复这样的输出。你必须自己编码。

void multiputchar(char c, size_t count)
{
    for (int i = 0; i < count; i++)
        putchar(c);
}

对于库函数,您可能关心是否putchar()失败,因此您最好编写:

int multiputchar(char c, size_t count)
{
    for (int i = 0; i < count; i++)
    {
        if (putchar(c) == EOF)
            return(EOF);
    }
    return (unsigned char)c;
}

但如果返回值总是被忽略,第一个更简单。强制转换是必要的,以确保如果您的char类型已签名,您可以区分 ÿ 的失败和成功输出(y-变音符号,U+00FF,LATIN SMALL LETTER Y WITH DIAERESIS,8859-1 中的 0xFF 和相关代码套)。

于 2012-11-12T18:06:51.327 回答
0

在 C 中,您还需要处理您使用的内存。因此,如果您想要一个“---”字符串,您还需要为该字符串分配空间。一旦分配了空间,您将用给定的字符填充它。

之后,您必须释放该区域。

所以:

char *charmul(char c, int n)
{
    int i;
    char *buffer; // Buffer to allocate
    buffer = malloc(n+1); // To store N characters we need N bytes plus a zero
    for (i = 0; i < n; i++)
        buffer[i] = c;
    buffer[n] = 0;
    return buffer;
}

然后我们需要添加错误检查:

char *charmul(char c, int n)
{
    int i;
    char *buffer; // Buffer to allocate
    buffer = malloc(n+1); // To store N characters we need N bytes plus a zero
    if (NULL == buffer)
         return NULL;
    for (i = 0; i < n; i++)
        buffer[i] = c;
    buffer[n] = 0;
    return buffer;
}

您的来源将变为:

#include <stdio.h>

// charmul here

int main (void)
{

    int height=0;
    int n=0;
    char symbol='#';
    printf("Height: ");
    scanf("%d",&height);
    n=height+1;
    while (n>=2)
        {
            char *s;
            s = charmul(symbol, n);
            printf("%s\n", s);
            free(s); s = NULL;
            n=n-1;
        }
    return 0;
}

另一种实现将寻求减少malloc' 的数量,以提高性能。为此,您还需要向函数传递一个指向前一个缓冲区的指针,如果更短,则可以回收而无需进一步malloc的 ,如果更长,将被free'd 并重新分配(或者可以使用realloc)。然后,您将free()只执行最后一个未回收的值:

char *charmul_recycle(char c, int n, char *prevbuf)
{
    int i;
    if (prevbuf && (n > strlen(*prevbuf)))
    {
        free(prevbuf); prevbuf = NULL;
    }
    if ((NULL == prevbuf)
    { 
        prevbuf = malloc(n+1); // To store N characters we need N bytes plus a zero
        if (NULL == prevbuf)
            return NULL;
    }
    for (i = 0; i < n; i++)
        prevbuf[i] = c;
    prevbuf[n] = 0;
    return prevbuf;
}


char *buffer = NULL;

while(n > 2)
{
     buffer = charmul_recycle(symbol, n, buffer);
     if (NULL == buffer)
     {
         fprintf(stderr, "out of memory\n");
         abort();
     }
     printf("%s\n", buffer);
     n--;
}

当然,整个事情可以通过单个直接分配和逐步缩短字符串(通过设置s[n]为零)来完成,但是我们不会使用“生成多个字符”功能:

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

int main (void)
{
    char *string;
    int height=0;
    int n=0;
    char symbol='#';
    printf("Height: ");
    scanf("%d",&height);
    n=height+1;
    string = malloc(n);        // allocate just enough memory (n is height+1)
    memset(string, symbol, n); // fill string with symbols

    while (--n) // with n ever decreasing...
    {
        string[n] = 0;            // Truncate string after n characters
        printf("%s\n", string);   // output string
    }
    free(string); // string = NULL; // finally free the string
    return 0;
}

更新(感谢 Jonathan Leffler):上面,有一个潜在的危险“过度优化”。在每次使用 之前stringstring正确地以零结尾(“ string[n] = 0;”)。但是,我已经分配了一个字符串变量并用东西填充它,并且没有立即零终止它,这仍然是事实。在上面的代码中,一切都很完美。这仍然是不好的编码实践,因为如果代码被重用并删除了循环,并且字符串用于其他目的(在这种情况下不太可能,但仍然......),未终止的string可能会成为一个微妙的错误。

最快的解决方法是在分配后终止:

    string = malloc(n);        // allocate just enough memory (n is height+1)
    memset(string, symbol, n-1); // fill string with symbols
    string[n-1] = 0;           // zero-terminate string

我现在偏离了原始主题,但这意味着在这种情况下,字符串正确地以零结尾两次。为避免这种情况,可以将代码重写为“剪切和粘贴安全”版本,还可以更清楚地显示额外的零作为 n 的添加:

    n=height;                   // Number of characters
    string = malloc(n+1);       // Allocate memory for characters plus zero
    memset(string, symbol, n);  // Store the characters
    string[n] = 0;              // Store the zero
    while (n)                   // While there are characters
    {
        printf("%s\n", string); // Print the string
        string[--n] = 0;        // Reduce it to one character less than before
    }

该循环现在接受任何具有有意义的有效字符串n,如果将其删除,则该字符串将保持可用状态。

于 2012-11-12T18:12:29.937 回答