URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 1753
[ Назад ]

Исходное сообщение
"символьный масив"

Отправлено Alexey , 09-Июн-03 14:18 
Народ, помогите плз, скажите почему хренов массив db при присваивании каждому последующему индексу значения, всем предыдущим тоже присваивает тоже значение?

#include <stdlib.h>
#include <stdio.h>

int
main(int argc, char *argv[])
{
        FILE            *fp;
        static char     word[10];
        char            *db[10];
        int             index_db=0;
        int             index=0;
        char            c;

        fp=fopen ("trafnet.conf", "r");

        while ((c = getc(fp)) != EOF) {
                if(c=='\n') {
                    db[index_db++]=word;
                    index=0;
                    continue;
                }
                word[index++] = c;
        }
        printf("%s\n", db[1]);
}


Содержание

Сообщения в этом обсуждении
"символьный масив"
Отправлено Тихий ужас , 09-Июн-03 15:40 
>Народ, помогите плз, скажите почему хренов массив db при присваивании каждому последующему
>индексу значения, всем предыдущим тоже присваивает тоже значение?
>
>#include <stdlib.h>
>#include <stdio.h>
>
>int
>main(int argc, char *argv[])
>{
>        FILE    
>        *fp;
>        static char  
>  word[10];
>        char    
>        *db[10];
>        int    
>         index_db=0;
>        int    
>         index=0;
>        char    
>        c;
>
>        fp=fopen ("trafnet.conf", "r");
>
>        while ((c = getc(fp))
>!= EOF) {
>            
>    if(c=='\n') {
>            
>        db[index_db++]=word;
>            
>        index=0;
>            
>        continue;
>            
>    }
>            
>    word[index++] = c;
>        }
>        printf("%s\n", db[1]);
>}

что написал, то и получил. У тя все элементы массива указателей всегда на одно и тоже и указывает (на word).


"символьный масив"
Отправлено Alexey , 09-Июн-03 15:44 
а как сделать чтобы она на содержимое word указывала?, как вообще можно инициализировать символьный массив? ...

"символьный масив"
Отправлено Тихий ужас , 09-Июн-03 20:45 
>а как сделать чтобы она на содержимое word указывала?, как вообще можно
>инициализировать символьный массив? ...

никак, указатель не на содержимое указывает, а на место в памяти. Нужно создать в памяти, записать туда, а потом указатель поставить на эту область. А вообще - читай Керниган, Ричи. Язык Си, там все это есть.


"символьный масив"
Отправлено Olej , 10-Июн-03 14:23 
>>Народ, помогите плз, скажите почему хренов массив db при присваивании каждому последующему
>>индексу значения, всем предыдущим тоже присваивает тоже значение?

А ещё намного (!) лучше - это общее решение подобного класса задач - это использовать для этого контейнерные классы STL (standard template library), это решение универсальное, эффективное, малотрудоёмкое... вполне стоит затрат на то, чтоб один рах потратить время на освоение STL. STL в едином виде существует практически для всех OS.

Правда - это всё для C++.


"символьный масив"
Отправлено SergCh , 10-Июн-03 11:32 
Учи malloc, free, new, delete.

А что б твой пример быстро заработал (на строках длиной<10 символов) достаточно заменить строку:

>        db[index_db++]=word;
на:
         word[index]='\0';
         db[index_db++]=strcpy(word);

Конечно, после использования массива, не забудь освободить память (free)


"символьный масив"
Отправлено Alexey , 10-Июн-03 12:04 
народ, а я так реализовал? сильно ли это противоречит правилам Си?

        FILE            *fp;
        static char     word[100][100];
        static char     *db[100];
        int             index_j=0;
        int             index_i=0;
        char            c;

while ((c = getc(fp)) != EOF) {
            if(c=='\n') {
                db[element++]=word[index_i];
                index_j=0;
                index_i++;
                continue;
                }
        word[index_i][index_j++] = c;
}


"символьный масив"
Отправлено SergCh , 10-Июн-03 14:54 
>народ, а я так реализовал? сильно ли это противоречит правилам Си?
1. А на хрена тебе в этом коде массив db?
2. Все строки по "правилам Си" лучше заканчивать нулевым символом (иначе как размер строки узнаешь, смотри в предыдущем моем примере присвоение '\0')

А лучше всего почитай книжку умную про строки и динамическую память.


"символьный масив"
Отправлено Olej , 10-Июн-03 12:15 
>Учи malloc, free, new, delete.
>
>А что б твой пример быстро заработал (на строках длиной<10 символов) достаточно
>заменить строку:
>
>>        db[index_db++]=word;
>на:
>         word[index]='\0';
>         db[index_db++]=strcpy(word);

А ещё точнее = strdup( word ) - strcopy() только копирует содержимое в уже размещённую память, и, скорее всего закончится core dump...


"символьный масив"
Отправлено Alexey , 10-Июн-03 13:09 
да но тут мне еще придется очищать массив word, перед следующим его заполнением...

"символьный масив"
Отправлено SergCh , 10-Июн-03 14:40 
>>Учи malloc, free, new, delete.
>>
>>А что б твой пример быстро заработал (на строках длиной<10 символов) достаточно
>>заменить строку:
>>
>>>        db[index_db++]=word;
>>на:
>>         word[index]='\0';
>>         db[index_db++]=strcpy(word);
>
>А ещё точнее = strdup( word ) - strcopy() только копирует содержимое
>в уже размещённую память, и, скорее всего закончится
Опечатался :) конечно strdup


"символьный масив"
Отправлено Alexey , 11-Июн-03 10:56 
хорошо, пока сделал с 2х мерным массивом, работает, но хочу переделать с использованием malloc, тут принцип, какой? создаю массив указателей, выделяю память для одной строки, присваиваю полученный указатель первому элементу массива, выделяю второй блок памяти, указатель присваиваю второму элементу массива и так далее для всех строк?

"символьный масив"
Отправлено David , 23-Июн-03 16:37 
Исправленная версия:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main (int argc, char *argv[])
{
        FILE        *fp;
        static char word[10];
        char        *db[10];
        int         index_db = 0;
        int         index    = 0;
        char        c;

        fp = fopen ("trafnet.conf", "r");

        memset (db, 0, 10);        
        *word = 0;

        while ((c = getc(fp)) != EOF)
        {
            if (c == '\n')
            {
                word[index]=0;
                if (index_db < 9) {
                    db[index_db++] = strdup (word);
                }
                else {
                    break;
                }
                index=0;
                continue;
            }
            if (index < 9) {
                word[index++] = c;
            }
        }
        printf ("%s\n", db[1]);
..........
    // очистка
        for (index_db = 0; index_db < 10; index++)
        {
           if (db[index_db]) {
              free (db[index_db]);
           }
        }
}


"символьный масив"
Отправлено Alexey , 25-Июн-03 12:14 
я так сделал, так нормально?
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main (int argc, char *argv[])
{
        FILE        *fp;
        static char word[100];
        char        *db[100];
        int         index_db = 0;
        int         index    = 0;
        char        c;

        fp=fopen ("/c/trafnet/trafnet.conf", "r");
        while ((c = getc(fp)) != EOF) {
            if(c=='\n') {
                db[element++]=word[index_i];
                index_j=0;
                index_i++;
                continue;
                }
        word[index_i][index_j++] = c;
        }


"символьный масив"
Отправлено XMan , 25-Июн-03 17:58 
Тебе что ли нужно в память файл построчно зачитать ?
Помоему проще будет загонять в "char **db" без промежуточных "word". Что-то типа:

    int i=0;
    char **db=(char **)malloc(STRING_COUNT*sizeof(char *));
    bzero(db,STRING_COUNT*sizeof(char *));

    while (! feof(fp)) {
        db[i]=(char *)malloc(MAX_LEN+1);
        bzero(db[i],MAX_LEN+1);
        fgets(db[i++],MAX_LEN,fp);
    };


где MAX_LEN - максимальная длина строки, STRING_COUNT - максимальное количество строк. Если использовать realloc(...), то можно отойти от этих ограничений.

PS. bzero сделано на всякий случай, дабы переполнения небыло.


"символьный масив"
Отправлено Alexey , 26-Июн-03 13:37 
Да, надо файл построчно,
но только чтобы в конце строки небыло '\n', а то MySQL не принемает потом все ити строки как пароль, имя хоста и юзера ))

"символьный масив"
Отправлено XMan , 26-Июн-03 17:26 
Тогда поправка. Вставляется после fgets:

if ((strlen(db[i-1]) != 0) && (db[i-1][strlen(db[i-1])-1] == '\n'))) db[i-1][strlen(db[i-1])-1]='\0';

Или во такая строка:

if (strchr(db[i-1],'\n')) *strchr(db[i-1],'\n')='\0';


"символьный масив"
Отправлено Alexey , 27-Июн-03 08:48 
фух )) дай бог помощи переварить теперь это )) в моей голове еще путаются понятия указателей ))