2014-01-30 3 views
0
#include<iostream> 
using namespace std; 
#include<conio.h> 

class student{ 
    int roll_no; 
    char name[15]; 
    float per; 
public: 
    student(int a, char b[15], float c){ 
     roll_no = a; 
     name[15] = b[15]; 
     per = c; 
    } 
    ~student(void){ 
     cout << "Student Details : \n\n" 
      << "Roll No : " << roll_no << "\n" 
      << "Name : " << name[15] << "\n" 
      << "Percentage : " << per << endl; 
    } 
}; 

int main(){ 
    student s(60,"Suraj Jadhav",25.25); 
    getch(); 
    return 0; 
} 

Выход: Student Детали:Строка не проходит через аргумент конструктора

Roll No : 60 
Name : 
Percentage : 25.25 

Имя не отображается строка .. Не уверен, что это проблема, но хотите, чтобы решить .. Пожалуйста, помогите. .

ответ

4

при объявлении

char name[15]; 

имя представляет собой массив из 15 символов. Параметр b является указателем («ожидается», чтобы указать массив из 15 символов).Заявление

name[15] = b[15]; 

копия только шестнадцатый элемент массива, на который указывает «Ъ» на 16-й элемент в поле «Имя» массива (отсчет начинается с нуля), так как есть 15 элементов в массиве нет никаких (так же, как вы печатаете имя [15]).

В C вы должны копировать каждый символ один за другим. Такие функции, как strcpy, позаботятся об этом, может быть опасно, если назначение недостаточно велико для размещения источника. В C++ вы должны попытаться избежать использования массива символов и использовать std :: string, а вместо этого возьмите копию. Вы также должны использовать список инициализаторов (синтаксис для инициализации элемента в конструкторе). Например:

#include<iostream> 
using namespace std; 
#include<conio.h> 

class student{ 
    int roll_no; 
    string name; 
    float per; 
public: 
    student(int a, const string &b, float c) 
     : roll_no(a), name(b), per(c) 
    { 
    } 
    ~student(){ 
     cout << "Student Details : \n\n" 
      << "Roll No : " << roll_no << "\n" 
      << "Name : " << name << "\n" 
      << "Percentage : " << per << endl; 
    } 
}; 

int main(){ 
    student s(60,"Suraj Jadhav",25.25); 
    getch(); 
    return 0; 
} 

Примечание: #include <conio.h> не является стандартным C/C++, это специфический заголовок MS-DOS. Постарайтесь, если это возможно, избегать :)

+0

Это должен быть комментарий. Он не отвечает на вопрос (каким бы он ни был). – 0x499602D2

+0

@ 0x499602D2 «Проблема вызвана использованием строк в стиле C, когда вы не понимаете, как они работают. Вместо этого используйте строки стиля C++, и у вас не будет этой проблемы». является допустимым ответом, IMO, если/до тех пор, пока OP не разъяснит, что по какой-то причине требуются массивы символов. Это примерно то, что в этом ответе. – hvd

+0

То, как вы сформировали ответ, на самом деле не отвечает на вопрос. Если вы пытаетесь сделать предложение, вам нужно разместить его как * комментарий *. – 0x499602D2

3
name[15] = b[15]; 

не будет копировать строку. Это будет просто скопировать один персонаж из b в name, в частности, один с индексом 15. (На самом деле, это на самом деле не определено поведение, поскольку каждый массив имеет только индексы 0..14.) Попробуйте это:

strcpy(name, b); 
2

Нельзя использовать необработанные указатели, если вы их не понимаете, вместо этого используйте std :: string. В любом случае ваш конструктор может быть исправлено, как это:

student(int a, const char *b, float c){ 
    roll_no = a; 
    strncpy(name, b, sizeof(name)); 
    per = c; 
} 

Существует проблема с strncpy() когда длина строки (что strlen() возвращается и за исключением \ 0 терминатора), где Ь указывает на равна или больше, чем размер name - это не будет положить \ 0 терминатор в целевую строку. Так код может быть безопаснее, таким образом:

student(int a, const char *b, float c){ 
    roll_no = a; 
    name[ sizeof(name) - 1 ] = 0; 
    strncpy(name, b, sizeof(name) - 1); 
    per = c; 
} 

снова работает с сырыми указателями является довольно сложным, и вы должны глубоко понять, что происходит там, чтобы написать безопасный код. Использование std :: string в C++ сделает вашу жизнь намного проще.

+0

Возможно, вам захочется рассмотреть, что это делает для 'name', когда' b [] 'is * long *, чем' sizeof (name) '-chars, включая его терминатор nulchar. Я спасу тебя в ожидании; он не завершает 'name []'. Любые будущие функции библиотеки строкового сканирования (например, 'strcpy',' strlen', 'strcmp' и т. Д.), Которые его используют, будут вызывать поиск неопределенного поведения для указанного терминатора. – WhozCraig

+0

@WhozCraig спасибо, добавил более безопасный вариант, я думаю, должен быть другой вариант strncpy, который всегда ставит терминатор в цель. – Slava

1

Вместо недействительного заявления

name[15] = b[15]; 

вы должны использовать C стандартную функцию strcpy, объявленный в заголовке

std::strcpy(name, b); 

Также правильное объявление конструктора будет выглядеть следующим образом

student(int a, const char b[15], float c); 

или

student(int a, const char b[], float c); 

или

student(int a, const char *b, float c); 

Эти три деклараций объявить ту же самую функцию.

Для того, чтобы конструктор безопасный я бы определил его как

student(int a, const char b[], float c){ 
     roll_no = a; 
     std::strncpy(name, b, 15); 
     name[14] = '\0'; 
     per = c; 
} 

Кроме того, это хорошая идея, чтобы присвоить имя магического числа 15 либо с помощью нумератор или статическую константу.

Смежные вопросы