【问题标题】:How to access a string from a pointer returned by a function in C如何从 C 中函数返回的指针访问字符串
【发布时间】:2018-07-03 23:39:18
【问题描述】:

我有一个函数返回指向 C 中的字符串的指针,我正在尝试访问整个字符串,但我不确定如何访问。

我有一个函数,它循环抛出一个包含学生数据的结构链接列表并获取学生的姓名。我想在每个字符串的末尾填充空格,以便它们的大小相同。所以我写了一个函数来填充字符串。该函数返回一个指向字符串的指针,但我不知道如何从指针访问整个字符串。我知道我可以使用 *pstring 来获取字符串的第一个字符,但我对如何获取其余部分有点迷茫。

这循环通过链表:

void myFunction(void) {

    pStudent = pHead;
    char paddedName[30];
    long nameLength = 0 ;

    while(pStudent->pNext != NULL){
        printf("%c,\n", *padstring(pStudent->name));
        strcpy(paddedName, padstring(pStudent->name));
        nameLength = strlen(paddedName);
        printf("%lu | %s | %s \n", nameLength, paddedName, pStudent->name);
        pStudent = pStudent->pNext;
    }
    printf("\n");

}

这填充并返回字符串:

char *padstring(char* string){

    char name[30];
    int i = 0;

    while(i < 30){
        if(i < strlen(string)){
            name[i] = string[i];
                    }
        else{
            name[i] = ' ';
        }
        i++;
    }
    printf("%s,\n", name);
    return name;

}

【问题讨论】:

  • 你不能像现在这样返回名字。它是一个在栈上创建的局部变量,当函数退出时“消失”。
  • 试图从函数中返回一个本地字符数组是一个常见的错误。许多基本类型(char、int、float、double 等)甚至结构都可以返回,因为编译器返回一个副本。本地字符数组变量是指向堆栈上“数组”(连续)字符的指针。指针的值正确返回,但函数退出时堆栈回滚,因此结果指向的字符数组不再有效。任何类型的本地数组也是如此。

标签: c string function pointers


【解决方案1】:

不必创建新字符串。您可以使用下面的格式说明符输出一个右填充到特定长度的字符串(例如:%-30s 右填充到 30 个字符):

printf("[%-10s]", name);

/* [Name      ] */

如果你确实创建了一个新字符串,你会想要返回一个有效的内存位置。与其返回指向本地堆栈的指针,不如使用malloc 分配内存,并在完成后记住free(或者传入调用者在堆栈上分配的数组)。

【讨论】:

  • 我只是建议最后一部分。 :)
【解决方案2】:

如果您希望将该内存返回给调用者,则需要在padstring() 中动态分配name

char *name = malloc(30);
if (name == NULL) {
    return NULL;
}

【讨论】:

    【解决方案3】:

    首先,您需要空终止您的字符串。其次,您需要使用 malloc 在堆上创建数组(确保在完成后释放内存)。

    【讨论】:

      【解决方案4】:

      我通常更喜欢在同一个字符串中进行填充。当然,您必须确保有足够的空间,您可以通过传递最大尺寸来做到这一点。我通过垫长度使其更灵活。可以通过传递要填充的字符来进一步改进它,以防它不总是空格。

      这是一个简单的例子。

      #include <string.h>
      #include <stdio.h>
      
      char* padstring(char *s, int maxlen, int padlen)
      {
          int len = strlen(s);
      
          if (len < padlen)
          {
              char *p = s + len;
              while ((len < maxlen) && (len < padlen))
              {
                  *p++ = ' '; // Add a space
                  *p = 0;     // Null terminate
                  len++;
              }
          }
      
          return s;
      }
      
      int main(int argc, char *argv[])
      {
          char s[50] = "Hello";
      
          printf("'%s'\n", padstring(s, sizeof(s), 30));
          return 0;
      }
      

      【讨论】:

        【解决方案5】:

        在您的情况下无需定义新函数。 只需使用sprintf() 用空格填充字符串。

        void myFunction(void) {
        
            // Declare max length of name
            const int MAX_LEN = 29;
        
            pStudent = pHead;
            char paddedName[MAX_LEN + 1];
            long nameLength = 0 ;
        
            while(pStudent->pNext != NULL){
                // Record origin length
                nameLength = strlen(pStudent->name);
                // Just write spaces after pStudent->name
                sprintf(pStudent->name + nameLength, "%-*s", MAX_LEN - nameLength, "");
        
                nameLength = strlen(pStudent->name);
                printf("%lu | %s | %s \n", nameLength, paddedName, pStudent->name);
                pStudent = pStudent->pNext;
            }
            printf("\n");
        
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-03-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-01-02
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多