Странные символы появляются при использовании функции strcat в C ++

Я новичок в C ++ и учусь в Руководстве MSDN C ++ для начинающих.

При попытке использовать функцию strcat она работает, но вначале я получаю три странных символа.

Вот мой код

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

int main() {
    char first_name[40],last_name[40],full_name[80],space[1];
    space[0] = ' ';
    cout << "Enter your first name: ";
    gets(first_name);
    cout << "Enter your last name: ";
    gets(last_name);
    strcat(full_name,first_name);
    strcat(full_name,space);
    strcat(full_name,last_name);
    cout << "Your name is: " << full_name;
    return 0;
}

А вот и вывод

Enter your first name: Taher
Enter your last name: Abouzeid
Your name is: Y}@Taher Abouzeid

Интересно, почему перед моим именем стоит Y} @?


person taabouzeid    schedule 05.12.2009    source источник
comment
ААААА! gets() подальше от нас! Он нас горит!   -  person Chris Lutz    schedule 06.12.2009


Ответы (6)


Создаваемый вами массив заполнен случайными данными. C ++ выделяет место для данных, но не инициализирует массив известными данными. Strcat прикрепит данные к концу строки (первый '\ 0'), поскольку массив символов не был инициализирован (и заполнен случайными данными), это не будет первый символ.

Это можно исправить, заменив

char first_name[40],last_name[40],full_name[80],space[1];

с участием

char first_name[40] = {0};
char last_name[40] = {0};
char full_name[80] = {0};
char space[2] = {0};

= {0} установит первый элемент в '\ 0', который является символом конца строки, а c ++ автоматически заполнит все неуказанные элементы '\ 0' (при условии, что указан хотя бы один элемент).

person Mekboy    schedule 05.12.2009
comment
Это работает с небольшими изменениями. Я заменил символьный пробел; с пробелом [2] = {0}; и это прекрасно работает. Пожалуйста, измените его в ответе, чтобы я мог его принять. - person taabouzeid; 06.12.2009

Вы не инициализируете full_name, устанавливая первый символ в '\ 0', поэтому в нем есть символы мусора, и когда вы strcat, вы добавляете свои новые данные после символов мусора.

person John    schedule 05.12.2009

Переменная full_name не инициализируется перед добавлением.

Измените это:

strcat(full_name,first_name);

к этому:

strcpy(full_name,first_name);
person Spire    schedule 05.12.2009
comment
Кроме того, space не завершается нулевым символом. - person Greg Hewgill; 06.12.2009
comment
Правда. Массив space должен быть определен с размером 2 и инициализирован строкой " " вместо символа ' '. - person Spire; 06.12.2009

Вы не видите никаких проблем в своем тесте, но ваша строка space также не заканчивается нулем после инициализации ее единственного символа с помощью ' '.

person Timbo    schedule 05.12.2009

Как говорили другие, вы должны инициализировать данные, но задумывались ли вы об изучении стандартной библиотеки С ++? Иногда это более интуитивно понятно и, вероятно, более эффективно.

С ним было бы:

string full_name=first_name+" "+last_name;

и вам не придется заморачиваться с завершающими нулевыми символами. Для справки перейдите на cplusplus.

Да, и полный рабочий пример, чтобы вы могли лучше понять (от оператора + =):

#include <iostream>
#include <string>
using namespace std;

int main ()
{
  string name ("John");
  string family ("Smith");
  name += " K. ";         // c-string
  name += family;         // string
  name += '\n';           // character

  cout << name;
  return 0;
}
person csiz    schedule 05.12.2009

Строки заканчиваются нулем в C и C ++ (функция strcat унаследована от C). Это означает, что когда вы указываете на случайный адрес памяти (новые переменные char [] указывают на адрес стека со случайным содержимым, которое не инициализируется), компилятор интерпретирует все, вплоть до первого символа \ 0 (null), как строку (и выйдет за пределы выделенного размера, если вы используете арифметику указателя).

Это может привести к очень непонятным ошибкам, проблемам с безопасностью (эксплойты переполнения буфера) и очень нечитаемому и неподдерживаемому коду. Современные компиляторы имеют функции, которые могут помочь в обнаружении таких проблем.

Вот хороший обзор ваших вариантов.

person cdonner    schedule 05.12.2009