Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 03.06.2011, 20:03   #1
rowlin
Пользователь
 
Регистрация: 14.12.2010
Сообщений: 31
По умолчанию '\0' конец строки

Доброго времения суток
В K&R на тему хеширования приводится хеш функция :

hash(s) /* form hash value for string */
char *s;
{
int hashval;
for (hashval = 0; *s != '\0'; )
hashval += *s++;
return(hashval % HASHSIZE);
}

ввожу данные:

printf("введите имя :");
scanf("\n%s",&name);
print....

...компиляция происходит успешно .. но отладчик ругается на for (hashval=0; *s !='\0'; *s++)..
..
введите имя :lexa
введите Имя2:lena

Program received signal SIGSEGV, Segmentation fault.
0x08048541 in hash (s=0x61786500 <Address 0x61786500 out of bounds>) at first.c:18

Разве '\0' конец строки не автоматически определяется ..или где ошибка?
ps : представил тут только ключевые моменты ...по сути мы передаем name в hash() в функции записи ..в случае надобности могу выложить весь исходник..
rowlin вне форума Ответить с цитированием
Старый 03.06.2011, 20:56   #2
Syuf
Форумчанин
 
Аватар для Syuf
 
Регистрация: 02.02.2010
Сообщений: 599
По умолчанию

Во-первых, выборосили вы юы эту книжку; во-вторых, моя "интуиция" подсказывает, что надо написать scanf("\n%s", name); без амперсанда; что у вас есть name?
"Лишь то читается легко, что написано с трудом; что в час написано, то в час и позабыто."
Syuf вне форума Ответить с цитированием
Старый 03.06.2011, 21:12   #3
rowlin
Пользователь
 
Регистрация: 14.12.2010
Сообщений: 31
По умолчанию

char *name;

без амперсанда:
Program received signal SIGSEGV, Segmentation fault.
0xb7ebb294 in _IO_vfscanf () ;

зря вы про книжку так - это ж классика..(даж распечатал)
rowlin вне форума Ответить с цитированием
Старый 03.06.2011, 21:20   #4
Syuf
Форумчанин
 
Аватар для Syuf
 
Регистрация: 02.02.2010
Сообщений: 599
По умолчанию

Классика 1945 года? Почему функции в старом стиле? Зачем != 0 писать? Зачем скобки в return?
По теме: а такой ввод строк тоже из этой книженции взяли?
Либо выделяйте память (не забыв ее освободить); либо выделяйте, забыв ее освободить (шутка); либо не выделяйте ничего, и используйте статический массив символов.
Цитата:
даж распечатал
Это веский повод ее сжечь. (есть, что сжигать)
"Лишь то читается легко, что написано с трудом; что в час написано, то в час и позабыто."
Syuf вне форума Ответить с цитированием
Старый 03.06.2011, 21:25   #5
Сtrl
C++
Форумчанин
 
Аватар для Сtrl
 
Регистрация: 27.03.2011
Сообщений: 803
По умолчанию

Syuf, глупость сказали! С каких пор scanf работает со значением, а не с адресом?
P.S. Туплю, это же C-строка. Тогда правильно говорите.

rowlin, так у вас *s++ в теле цикла или в заголовке? Вы написали:
Код:
for (hashval = 0; *s != '\0'; )
А отладчик ругается на:
Код:
for (hashval=0; *s !='\0'; *s++)
Ищете информацию по C++?
cplusplus.com
Сtrl вне форума Ответить с цитированием
Старый 03.06.2011, 21:35   #6
Syuf
Форумчанин
 
Аватар для Syuf
 
Регистрация: 02.02.2010
Сообщений: 599
По умолчанию

Цитата:
С каких пор scanf работает со значением, а не с адресом?
Ctrl Так она и работает с адресом, адресом начала строки. Глупость говорите как раз вы: адресс указателя scanf'у нафиг не нужен, она читает строку. И с амперсандом работать не будет.
Другое дело, что если это статический массив, то эти адресса (str и &str) совпадают. Но тут это не статический массив.
"Лишь то читается легко, что написано с трудом; что в час написано, то в час и позабыто."
Syuf вне форума Ответить с цитированием
Старый 03.06.2011, 21:38   #7
Syuf
Форумчанин
 
Аватар для Syuf
 
Регистрация: 02.02.2010
Сообщений: 599
По умолчанию

Цитата:
так у вас *s++ в теле цикла или в заголовке?
P.S. Тело цикла начинается после его заголовка.
"Лишь то читается легко, что написано с трудом; что в час написано, то в час и позабыто."
Syuf вне форума Ответить с цитированием
Старый 03.06.2011, 21:39   #8
rowlin
Пользователь
 
Регистрация: 14.12.2010
Сообщений: 31
По умолчанию

вот...
Код:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct nlist  { 
      char *name;
      char *def;
      struct nlist *next; 
 };
#define    HASHSIZE     100
static struct nlist *hashtab[HASHSIZE];

  hash(s)   /* form hash value for string */
  char *s;
  {
   int hashval;
    for (hashval=0; *s !='\0'; *s++)
      // for (hashval = 0; *s != '\0'; )
       hashval ++;
   return(hashval % HASHSIZE);
  }

 struct nlist *lookup(s) 
 char *s;
 {
 struct nlist *np;
 for (np = hashtab[hash(s)]; np != NULL;np=np->next)
   if (strcmp(s, np->name) != 0)//если совпадений нет
   return(np);  /* found it */
 return(NULL);    /* not found */
 }

struct nlist *install(name, def) /* put (name, def) */
    char *name, *def;
    {
      struct nlist *np, *lookup();
  int hashval;
  if((np = lookup(name)) == NULL) { /* not found */
   np = (struct nlist *) malloc(sizeof(*np));
   if (np == NULL)
      return(NULL);
   if (name == NULL)
      return(NULL);
   hashval = hash(np->name);
   np->next = hashtab[hashval];
   hashtab[hashval] = np;
  } else        /* already there */
       free(np->def);/* free previous definition */
     if ((strcpy(np->def,def)) == NULL)
       return (NULL);
  return(np);
}      

char main(){
  int a;
  char *name,*def;
  for(a=0;a<3;a++){
  printf("введите имя :");
    scanf("\n%s",&name); 
    printf("\nвведите Имя2:");
    scanf("\n%s",&def);
    if (install(name,def)!=NULL) printf("end");
  }
}
Сtrl

Цитата:
А отладчик ругается на:
Код:

for (hashval=0; *s !='\0'; *s++)
то же самое ...
0x0804852f in hash (s=0x656565 <Address 0x656565 out of bounds>) at first.c:17
rowlin вне форума Ответить с цитированием
Старый 03.06.2011, 21:45   #9
Syuf
Форумчанин
 
Аватар для Syuf
 
Регистрация: 02.02.2010
Сообщений: 599
По умолчанию

Короче, hash был правильный, main надо такой:
Код:
char main(){
  int a;
  char name[80] = {'\0'}, def[80] = {'\0'};
  for(a=0;a<3;a++){
  printf("введите имя :");
    scanf("\n%s",name); 
    printf("\nвведите Имя2:");
    scanf("\n%s",def);
    if (install(name,def)!=NULL) printf("end");
  }
}
"Лишь то читается легко, что написано с трудом; что в час написано, то в час и позабыто."
Syuf вне форума Ответить с цитированием
Старый 03.06.2011, 22:03   #10
rowlin
Пользователь
 
Регистрация: 14.12.2010
Сообщений: 31
По умолчанию

Syuf

Cпасибо ..заработало ..

Насчет книжки ..возможно вы правы .. но .. мож что из нового по С посоветуете ..
ps: желательно без использования windows библиотек (<conio.h>...)
rowlin вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Найти конец строки или символ Blourid Общие вопросы .NET 2 17.12.2010 01:09
Дописать строки в конец *.ini Shouldercannon Общие вопросы Delphi 10 12.01.2010 14:30
Builder 2006 Не находит конец строки coper Общие вопросы C/C++ 0 22.11.2009 20:28
Программа считает пробел за конец строки AxenicX Общие вопросы C/C++ 3 12.11.2009 10:16
как добавить строку в конец строки Damhurz PHP 4 16.04.2009 14:35