Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Си. Функция, возвращающаяя указатель на массив.

38K
01 декабря 2009 года
Exmas
9 / / 06.07.2008
Помогите решить задание. Дан текстовой файл, содержащий в каждой строке по два числа. Необходимо открыть файл, читать строки и если одно из чисел в строке меньше нуля, то найти сумму этих чисел. Записать суммы в другой текстовой файл через запятую. После последней суммы необходимо поставить точку. Алгоритм вычисления сумм сделать при помощи функции.
Я сделал вот так, но массив содержит какую-то ерунду.
Код:
#include "stdio.h"
int func(FILE *file);
int main(){
    FILE *file,*file2;
    int str[20],c,l;
    file=fopen("C:/lab/1.txt","r");
    file2=fopen("C:/lab/2.txt","w");
    c=1;
    *str=func(file);
    l=str[19];
    while (c<l){
        if (c+1==l) fprintf(file2,"%d.",str[c]); else fprintf(file2,"%d,",str[c]);
        c+=1;
    }  
}

int func(FILE *file){
    l=1;
    while (fscanf(file,"%d %d",&a,&b)!=EOF){
        printf("%d %d\n",a,b);
        if (a<0 || b<0){ str[l]=a+b; l+=1;}
        }
    str[19]=l;
    return *str;
}
12K
01 декабря 2009 года
Ghox
297 / / 26.07.2009
Скажите пожалуйста, а у вас эта программа вообще компилится, и хоть как-то работает? А то я вижу здесь пару ошибок, из-за которых программа не должна компилиться:
Код:
[COLOR="Red"]#include "stdio.h" // правильно #include <stdio.h>[/COLOR]
int func(FILE *file);
int main(){
    FILE *file,*file2;
    int str[20],c,l;
    file=fopen("C:/lab/1.txt","r");
    file2=fopen("C:/lab/2.txt","w");
    c=1;
    *str=func(file);
    l=str[19];
    while (c<l){
        if (c+1==l) fprintf(file2,"%d.",str[c]); else fprintf(file2,"%d,",str[c]);
        c+=1;
    }  
}

int func(FILE *file){
    l=1;
    while (fscanf(file,"%d %d",&a,&b)!=EOF){
        printf("%d %d\n",a,b);
        if (a<0 || b<0){ [COLOR="Red"]str[l][/COLOR]=a+b; l+=1;}
        }
    [COLOR="Red"]str[19]=l; // массив str объявлен в main, здесь не виден[/COLOR]
    return *str;
}
34K
01 декабря 2009 года
muturgan
96 / / 01.10.2009
Цитата: Ghox

#include "stdio.h" // правильно #include <stdio.h>


Из-за этого ошибки быть не может. Имена заголовочных файлов можно писать и в кавычках.

38K
01 декабря 2009 года
Exmas
9 / / 06.07.2008
Код:
#include <stdio.h>
int func(FILE *file);
int main(){
    FILE *file,*file2;
    int str[20],c,l;
    file=fopen("C:/lab/1.txt","r");
    file2=fopen("C:/lab/2.txt","w");
    c=1;
    *str=func(file);
    l=str[19];
    while (c<l){
        if (c+1==l) fprintf(file2,"%d.",str[c]); else fprintf(file2,"%d,",str[c]);
        c+=1;
    }  
}

int func(FILE *file){
    int a,b,l,str[20];
    l=1;
    while (fscanf(file,"%d %d",&a,&b)!=EOF){
        printf("%d %d\n",a,b);
        if (a<0 || b<0){ str[l]=a+b; l+=1;}
        }
    str[19]=l;
    return *str;
}

так тоже не хочет работать...
34K
01 декабря 2009 года
muturgan
96 / / 01.10.2009
Цитата: Exmas
и если одно из чисел в строке меньше нуля, то найти сумму этих чисел.



Я так понимаю, что ровно одно число должно быть меньше нуля, поэтому попробуйте заменить Ваше условие

 
Код:
if(a<0 || b<0)

например на такое
 
Код:
if ( (a<0 && b>=0) || (a>=0 && b<0) )

Также, как вариант решения, сделайте возвращаемый тип Вашей функции void, а указатель на массив передайте в качестве параметра.
38K
01 декабря 2009 года
Exmas
9 / / 06.07.2008
Да, я не правильно написал - хотя бы одно из чисел меньше нуля.
38K
01 декабря 2009 года
Exmas
9 / / 06.07.2008
Цитата: muturgan

Также, как вариант решения, сделайте возвращаемый тип Вашей функции void, а указатель на массив передайте в качестве параметра.



А как это?

38K
01 декабря 2009 года
Exmas
9 / / 06.07.2008
Цитата: Ghox
Скажите пожалуйста, а у вас эта программа вообще компилится, и хоть как-то работает? А то я вижу здесь пару ошибок, из-за которых программа не должна компилиться:


Компилится, работает, но в файл ничего не пишет. Пробовал в разных местах программы выводить на экран элементы массива str, в функции все элементы правильные, а возвращаемые ей значения совсем не такие, какие должны быть.

12K
01 декабря 2009 года
Ghox
297 / / 26.07.2009
Цитата: Exmas
Компилится, работает, но в файл ничего не пишет. Пробовал в разных местах программы выводить на экран элементы массива str, в функции все элементы правильные, а возвращаемые ей значения совсем не такие, какие должны быть.


Если вы про первый вариант программы, по которому я сделал замечания, то я очень удивлен если он у вас компилится. Насчет "stdio.h", muturgan может и прав, но из-за отсутствия str точно должно было не компилиться.

И второй вариант вы кстати неправильно сделали - объявили локальный массив внутри функции, который просто исчезает после завершения работы функции.

Да и функция у вас возвращает не "указатель на массив", а просто значение int, которое вы вот здесь:

 
Код:
*str=func(file);

присваиваете первому элементу массива str.
Цитата: Exmas
А как это?


Полагаю примерно это имелось в виду:

Код:
#include <stdio.h>
void func(FILE *file, int *str);
int main(){
    FILE *file,*file2;
    int str[20],c,l;
    file=fopen("C:/lab/1.txt","r");
    file2=fopen("C:/lab/2.txt","w");
    c=1;
    func(file, str);
    l=str[19];
    while (c<l){
        if (c+1==l) fprintf(file2,"%d.",str[c]); else fprintf(file2,"%d,",str[c]);
        c+=1;
    }  
}

void func(FILE *file, int *str){
    int a,b,l;
    l=1;
    while (fscanf(file,"%d %d",&a,&b)!=EOF){
        printf("%d %d\n",a,b);
        if (a<0 || b<0){ str[l]=a+b; l+=1;}
        }
    str[19]=l;
}

Update. И еще я заметил, что вы в циклах отсчет переменных, используемых в качестве индексов для обхода элементов массивов, начинаете с единицы [noparse](c = 1; l = 1;)[/noparse]. Может быть, лучше начинать с нуля?
38K
01 декабря 2009 года
Exmas
9 / / 06.07.2008
Огромное вам спасибо! Теперь программа работает так, как нужно.
Да, первый вариант не компилится. Даже не знаю откуда я его взял, может быть скопировал из какого-то промежуточного варианта программы.
Сделал отсчет с нуля для переменных, используемых в циклах. Да, так лучше.
Еще вопрос: чтобы присваивать значение массиву, а не первому его элементу, нужно писать без указателя?
12K
01 декабря 2009 года
Ghox
297 / / 26.07.2009
Цитата: Exmas
Еще вопрос: чтобы присваивать значение массиву, а не первому его элементу, нужно писать без указателя?


Если вы имеете в виду под "присваивать значение массиву" следующее: есть два массива, и нужно присвоить каждому элементу одного массива значение соответственного (по номеру индекса) элемента другого массива, то сделать это одной операцией "=" нельзя, нужно поэлементно выполнить присваивание.

Применительно к вашей задаче - можно использовать создание массива динамически. Внутри функции func можно создать массив динамически (через функцию malloc если в C, если в C++ - то можно также через оператор new), создав указатель, выделив область памяти (через malloc / new) и установив указатель на начало этой области, а затем работая с указателем как будто это массив. И потом вернуть значение указателя как результат выполнения функции:

Код:
#include <stdio.h>
#include <stdlib.h>
int* func(FILE *file, int size);
int main(){
    FILE *file,*file2;
    int c, l, maxSize = 20;
    int *str;
    file=fopen("C:/lab/1.txt","r");
    file2=fopen("C:/lab/2.txt","w");
    c=1;
    str = func(file, maxSize);
    l=str[maxSize - 1];
    while (c<l){
        if (c+1==l) fprintf(file2,"%d.",str[c]); else fprintf(file2,"%d,",str[c]);
        c+=1;
    }  
}

int* func(FILE *file, int size){
    int a,b,l;
    int *str = (int*)malloc(size * sizeof(int));
    l=1;
    while (fscanf(file,"%d %d",&a,&b)!=EOF){
        printf("%d %d\n",a,b);
        if (a<0 || b<0){ str[l]=a+b; l+=1;}
        }
    str[size - 1]=l;
    return str;
}

И вообще - похоже вы очень слабо представляете как организована работа с массивами и указателями (хотя бы судя по вашему выражению "писать без указателя"), советую получше почитать в учебнике про массивы, указатели, и как массивы связаны с указателями.
38K
01 декабря 2009 года
Exmas
9 / / 06.07.2008
Все понятно! Спасибо. Учебники обязательно почитаю, просто тот учебник, по которому учимся мы, рассматривает массивы достаточно поверхностно.
41K
01 декабря 2009 года
Alex57
44 / / 22.02.2009
Цитата: Exmas
Компилится, работает, но в файл ничего не пишет. Пробовал в разных местах программы выводить на экран элементы массива str, в функции все элементы правильные, а возвращаемые ей значения совсем не такие, какие должны быть.


Возвращаемое функцией значение - это только str[0].
См. комментарии.

Код:
#include <stdio.h>
int func(FILE *file);
int main(){
    FILE *file,*file2;
    int str[20],c,l;
    file=fopen("C:/lab/1.txt","r");
    file2=fopen("C:/lab/2.txt","w");
    c=1;
    *str=func(file); [COLOR="Blue"]// *str - это начальный элемент массива[/COLOR]
    // [COLOR="Red"] *str это то же самое что  str[0][/COLOR]
    l=str[19];
    [COLOR="Blue"]// кроме str[0] функция func  никак не меняет значения массива str (того, который в main )
    // str[], объявленный в main, и str[], объявленный в func - [/COLOR][COLOR="Red"]это разные массивы[/COLOR]
    while (c<l){
        if (c+1==l) fprintf(file2,"%d.",str[c]); else fprintf(file2,"%d,",str[c]);
        c+=1;
    }  
}

int func(FILE *file){
    int a,b,l,str[20];
    l=1;
    while (fscanf(file,"%d %d",&a,&b)!=EOF){
        printf("%d %d\n",a,b);
        if (a<0 || b<0){ str[l]=a+b; l+=1;}
        }
    str[19]=l;
    [COLOR="Blue"]// Вы записываете числа в локальный массив  str[]
    // После выхода из функции этот массив перестаёт существовать[/COLOR]
    return *str;
}
38K
01 декабря 2009 года
Exmas
9 / / 06.07.2008
Я это уже понял, но все равно спасибо!
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог