Запрос конкатенации строк c ++ - PullRequest
0 голосов
/ 16 ноября 2009
#include <stdio.h>
#include <string.h>
#include <conio.h>
#include <iostream>

using namespace std;


char a[21]; // If this is put inside the function unter -> junk output
char* b="";

void unter()
    {
        char *new_str = "";


        strcpy(a, new_str);

        char str_temp[10]="";
        int chnum =0, neighbor1=3, neighbor2=5, mynode=4;

        sprintf(str_temp,"%d",chnum);

        b = strcat(a, str_temp);
        b = strcat(b, "_from");
        sprintf(str_temp,"%d",mynode);
        b = strcat(b, str_temp);
        b = strcat(b, "to");
        sprintf(str_temp,"%d",neighbor1);
        b = strcat(b, str_temp);


    }

int main()
{
    unter();
    cout << a;
    cout << b;
    std::cin.get();
}

Это мой код на C ++. Я не уверен, что массив символов «а» также имеет те же значения, что и «б». И более того, когда я объявляю 'a'

char a[21]; 

внутри функции unter (), я получаю некоторое ненужное значение для 'b' (как вывод). Не хочешь объяснить, как?

Ответы [ 7 ]

3 голосов
/ 16 ноября 2009

a - это массив символов, а b - указатель, указывающий на a, поэтому при их печати они всегда печатают одно и то же. Когда вы перемещаете объявление для a в unter, оно уничтожается при возврате unter, оставляя b неуклюжий указатель, поэтому вы получаете мусор при его печати. ​​

3 голосов
/ 16 ноября 2009
b = strcat(a, str_temp);

, вероятно, является причиной вашей проблемы, поскольку возвращаемое значение из strcat () является первым параметром, который был передан ему, поэтому вы видите, что a и b становятся равными, поскольку b установите в этом вызове a.

2 голосов
/ 16 ноября 2009

Вы можете сделать всю конкатенацию и sprintf в одну строку.

char* b="";
void unter()
    {
        int chnum =0, neighbor1=3, neighbor2=5, mynode=4;
        char str_temp[21];
        sprintf(str_temp,"%d_from%dto%d", chnum, mynode, neighbor1);
        b = new char[strlen(str_temp)+1];
        b = strcpy(b, str_temp);
    }

Единственная забавная вещь, которую вы должны помнить, чтобы удалить b, когда вы закончите. Другой вариант - использовать буфер и sprintf непосредственно к нему:

char a[21]; 
void unter()
    {
        int chnum =0, neighbor1=3, neighbor2=5, mynode=4;
        char str_temp[21];
        sprintf(a,"%d_from%dto%d", chnum, mynode, neighbor1);
    }
2 голосов
/ 16 ноября 2009

strcat () возвращает результат операции конкатенации, поэтому

b = strcat(a, str_temp);

в результате b указывает на массив a []. Последующие операции strcat () эффективно делают то же самое, поэтому в результате b указывает на a [], как вы заметили. Если вы объявите [] внутри unter (), он будет иметь локальную область действия этой функции, в результате глобальная переменная b будет указывать на случайное / неопределенное содержимое памяти после выхода из вызова unter ().

Мягко стоит отметить, что вы делаете много работы, которую можно было бы выполнить легче с

sprintf(a, "%d_from%dto%d", chnum, mynode, neighbor1);
1 голос
/ 16 ноября 2009

Если вы объявите a внутри функции unter(), то она будет ограничена только внутри этой функции. Попытка напечатать b извне, функция напечатает ненужную информацию, поскольку она указывает на a, который уже уничтожен.

Это классический пример того, почему вы всегда должны следить за тем, чтобы не указывать на локальную переменную из глобальной.

1 голос
/ 16 ноября 2009

Когда вы определяете a внутри функции, память для переменной a выделяется в стеке. Эта память уничтожается при выходе из функции. Ваш указатель b указывает на начальный адрес a. Теперь, если вы пытаетесь получить доступ к b вне функции, она указывает на область памяти, которая уже разрушена и содержит значения мусора. По сути, b становится висящим указателем.

1 голос
/ 16 ноября 2009

В дополнение к другим подсказкам, вы должны обратить внимание на строку

b = strcat(b, str_temp);

, что кажется довольно неподходящим для b, просто определяется как указатель на символ для хранения одного байта ("" определяет пустую строку, то есть массив символов с единственным элементом, содержащим '\ 0')

Таким образом, когда strcat добавляет b, он создает переполнение буфера.

Редактировать : На самом деле я только что заметил, что b был назначен для указания на a (благодаря строке, предшествующей упомянутой), так что тогда все будет в порядке, так как a может иметь место для этого. .. Однако не имеет смысла требовать две переменные.

Возможно, вы не понимаете, что хотя strcat () возвращает указатель, этот возврат не нужно «потреблять», это просто удобство, потому что когда мы объединяем команды в цепочку. Другими словами, вы можете просто написать:

strcat(a, str_temp);

Не требуется никакой символ * b.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...