Как добавить символы для достижения максимального размера символа [] - PullRequest
3 голосов
/ 21 декабря 2010

У меня есть следующая часть кода:

for(int i=0;i<n;i++)
{
    printf("Student %d\n",i+1);
    printf("Enter name : ");
    scanf("%s",&(student+i)->name);
    fflush(stdin);

    lengthName = strlen((student+i)->name);
    while(lengthName !='\0')
    {

    }} 

если длина меньше 10, добавятся дефисы до максимального размера. Пример: Джон = >> 6 дефисов будут добавлены

Я знаю, как сделать это в csharp, но не могу понять это в c. Могут ли некоторые из вас дать мне немного света, пожалуйста?

PS: О, да, имя переменной - имя символа [10 + 1], и оно является частью структуры, называемой student.

Ответы [ 7 ]

3 голосов
/ 21 декабря 2010

Это так просто, что кажется, что я что-то упускаю.

lengthName = strlen(student[i].name);
while (lengthName < 10)
  student[i].name[lengthName++] = '-';
student[i].name[lengthName] = '\0';

Возможно, вас смущает (предположительно) владение C # первоклассным строковым типом? Нет такой вещи в C, только голые массивы символов; который одновременно утомителен (вы должны все управлять памятью самостоятельно) и освобождает (как вы видите выше).

1 голос
/ 21 декабря 2010
while(lengthName < 10)  
{  
    student[i]->name[lengthName++] = '-'; // add this line  
}  
student[i]->name[lengthName] = 0;  // and this line 
1 голос
/ 21 декабря 2010

Как насчет этого?

// Pre-fills with hyphens.
memset(student[i].name, '-', sizeof(student[i].name) - 1);
scanf("%10s", student[i].name);
0 голосов
/ 21 декабря 2010

Используйте fgets() для чтения ввода, с пониманием, что он сохранит символ новой строки в буфере, если есть место; вам придется добавить некоторые специальные обработки для этого.

Обратите внимание, что поведение fflush() равно , не определено для входных потоков; Вы не можете удалить нежелательный ввод, вызвав fflush(stdin);.

Тогда нужно задать оставшиеся символы дефисам.

if (fgets(students[i].name, sizeof students[i].name, stdin) != NULL)
{
  size_t max = sizeof students[i].name - 1;
  size_t len = 0;

  char *newline = strchr(students[i].name, '\n');
  if (newline)
    *newline = 0; // clear out newline
  else
  {
    while (fgetc(stdin) != '\n') // clear out remaining input; 
                                 // name potentially truncated
      ;
  }

  // pad remainder with hyphens
  len = strlen(students[i].name);
  while (len < max)
    students[i].name[len++] = '-';
  students[i].name[max] = 0;
}
0 голосов
/ 21 декабря 2010

Модифицированная версия идеи @ kotlinski:

#define NAME_SIZE 10

fgets(student[i].name, NAME_SIZE, stdin);
lengthName = strlen(student[i].name);
if (lengthName > 0 && student[i].name[lengthName-1] == '\n') {
    --lengthName;
}
if (lengthName < NAME_SIZE) {
    memset(student[i].name + lengthName, '-', NAME_SIZE - lengthName);
    student[i].name[NAME_SIZE] = '\0';
}
0 голосов
/ 21 декабря 2010

Ваша переменная char name[10 + 1];, очевидно, имеет длину 11 байтов. Добавление чего-либо более чем 11 байтов приведет к переполнению буфера.

Здесь может произойти переполнение буфера:

scanf("%s",&(student+i)->name);

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

Исправление переполнения буфера

Один простой способ решить эту проблему - это заставить сам scanf ограничить число читаемых символов:

// read only 10 chars, since `name` can only 
// hold 10 chars, plus the extra NULL char
scanf("%10s", &(student+i)->name);

Предварительное заполнение дефисами

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

// pre-fill your data with hypens.
memset((student+i)->name, '-', sizeof((student+i)->name) - 1);

// read only 10 chars, since `name` can only 
// hold 10 chars, plus the extra NULL char
scanf("%10s", &(student+i)->name);
0 голосов
/ 21 декабря 2010

Попробуйте следующее:

while (lengthName < 10)
{
    (student+i)->name[lengthName++] = '-';
}
...