Read lines to array of strings [duplicate] - c

This question already has answers here:
Passing two-dimensional array via pointer
(9 answers)
Closed 9 years ago.
I am trying to make function that fills array of strings with lines from file, but the compiler (GCC) still giving me a warning. Than if I try to run compiled app, it gives me "Segmentation fault" error
Source code:
main
#include <stdio.h>
#include "getAdresses.h"
int main(int argc, char **argv){
char adresses[1024][128];
getAdresses(adresses);
printf("%s", adresses[1]);
}
getAdresses
include <stdio.h>
int getAdresses(char **adresses){
FILE *fr;
fr = fopen("adresses", "r");
int i = 0;
while(adresses[i-1][0] != EOF){
fscanf(fr, "%s\n", &adresses[i]);
i++;
}
}
It's giving me this error:
main.c: In function ‘main’:
main.c:9:2: warning: passing argument 1 of ‘getAdresses’ from incompatible pointer type [enabled by default]
In file included from main.c:3:0:
getAdresses.h:1:5: note: expected ‘char **’ but argument is of type ‘char (*)[128]’

First of all you have done the typical mistake: char ** is not the same as a char (*)[128]. The latter is the type of adresses.
You get the segmentation fault when you try to dereference it in line
while(adresses[i-1][0] != EOF)
Aside from the fact that adressing [i-1] for i = 0 will give you bad results you should define your function as
int getAdresses(char (*adresses)[128])
to be able to pass your two dimensional array correctly and fscanf should scan into your actual line buffer and if you are reading line by line use fgets:
while(fgets(adresses[i], 128, fr)) i++;

when you pass adresses[1024][128] to a function, the compiler will only do one step of decay, and the parameter type should be char (*)[128] instead of char ** .
You also need to pass its first dimension to the function, which means
int getAdresses(char (int (*arr)[128], int x)
check the c-faq for a detailed explanation for this issue.

The array you allocated declaring
char adresses[1024][128]
is actually a char* (it isn't but it's much closer to it than to char**).
The double diemension accessor is actually just a syntactic sugar for [x+y*width].
To pass the array as a parameter use:
int getAdresses(char (*adresses)[128])

Related

How to fix function calling warnings in c?

struct reviewStruct {
char reviewer[MAX_STR];
int feedback[NUMBER_MOVIES];
};
int readMovies(FILE *file, char movieNames[NUMBER_MOVIES][MAX_STR])
int readReviews(FILE *file, struct reviewStruct reviews[NUMBER_REVIEWERS])
int main() {
FILE *file;
char movieNames[NUMBER_MOVIES][MAX_STR];
char reviews [NUMBER_REVIEWERS];
myFile("cisfile.txt");
readMovies(file, movieNames);
readReviews(file, reviews);
}
This is my main function along with the function definitions, when I compile the program I get the following errors:
"warning: passing argument 2 of ‘readReviews’ from incompatible pointer type" for the line: "readReviews(file, reviews);"
"warning: ‘file’ is used uninitialized in this function" for the line: "readMovies(file, movieNames);"
How do I fix these two errors?
I took your code and tried to make it run.
#include <stdio.h>
#include <stdlib.h>
#define MAX_STR 10
#define NUMBER_MOVIES 3
#define NUMBER_REVIEWERS 2
struct reviewStruct {
char reviewer[MAX_STR];
int feedback[NUMBER_MOVIES];
};
int readMovies(FILE *file, char movieNames[NUMBER_MOVIES][MAX_STR])
{
printf("hi\n");
}
int readReviews(FILE *file, void *reviews)
{
printf("bye\n");
}
int main(void)
{
FILE *myFile;
char movieNames[NUMBER_MOVIES][MAX_STR];
char reviews [NUMBER_REVIEWERS];
myFile = fopen("cisfile.txt","r");
readMovies(myFile, movieNames);
readReviews(myFile, reviews);
fclose(myFile);
return 0;
}
With these assumptions runs without any warnings.
I am using gcc 8.3.0 without any options.
1. First warning:
As per what #kaylum said. You are declaring char reviews[MUMBER_REVIEWERS], but when you defined the parameters for your function: int readReviews(FILE *file, struct reviewStruct reviews[NUMBER_REVIEWERS], it is clear that the parameter concerned by the array should be of type struct reviewStruct.
So in the line where you got the warning change: char reviews [NUMBER_REVIEWERS]; to struct reviewStruct reviews[NUMBER_REVIEWERS];. That should be a pointer to a structure type, not a pointer to a character type. Or if you want to go more in detail: It is a pointer to an array of structures, the type of the array is determined by the type of elements it holds.
2. Second warning:
Now let's take a look at the second warning: warning: ‘file’ is used uninitialized in this function" for the line: "readMovies(file, movieNames)
As the warning says. Your pointer file was not initialized. Take it as a rule, that you cannot use a pointer without initializing it to something to point to. I believe that you are trying to read from a stream. So just in case you need it, you perhaps may be willing to use the function fopen(), which returns a pointer to a stream.

function warnings C: "warning: type of ‘char_array’ defaults to ‘int’"

#include <stdio.h>
#include <string.h>
int myprint(char_array){
char mystring[80];
strcat(mystring, "\n");
printf("%s", mystring);
return 0;
}
int main(int argc, char** argv){
int count = 5;
char letter = 'c';
printf("decimal: %d, char: %c\n", count, letter);
myprint("sup");
return 0;
}
I get warnings on compile:
cchilders:~/projects/buildyourownlisp_in_C/ch3 [master]$ compile basics.c basics
basics.c: In function ‘myprint’:
basics.c:4:5: warning: type of ‘char_array’ defaults to ‘int’
int myprint(char_array){
^
It compiles, but my myprint function doesn't work:
cchilders:~/projects/buildyourownlisp_in_C/ch3 [master]$ ./basics
decimal: 5, char: c
I see this answer warning: return type defaults to ‘int’ [-Wreturn-type] but doesn't apply to me since I did declare int main(...)
I also see this declaration of functions:
return_type function_name( parameter list ) {
body of the function
}
And for myprint I declare as taking int and return 0. What does this warning mean and why doesn't my function work? Thank you
ANSWER:
void myprint(char mystring[]){
strcat(mystring, "\n");
printf("%s", mystring);
}
quiets the warnings, but causes Segmentation fault (core dumped)
Changing to
void myprint(char[] mystring){
strcat(mystring, "\n");
printf("%s", mystring);
}
makes it worse:
cchilders:~/projects/buildyourownlisp_in_C/ch3 [master]$ cc -std=c99 -Wall basics.c -o basics
basics.c:4:21: error: expected ‘;’, ‘,’ or ‘)’ before ‘mystring’
void myprint(char[] mystring;){
^
basics.c: In function ‘main’:
basics.c:15:5: warning: implicit declaration of function ‘myprint’ [-Wimplicit-function-declaration]
myprint("sup");
^
I also tried
void myprint(char[] mystring;){...
and
void myprint(char[] mystring,){...
As others have pointed out, you didn't specify a type for char_array, so it is assumed to be int. Changing it to char char_array[] fixes this.
Your other problem is that you're passing a string constant ("sup") to this function and are then attempting to modify it. String constants are stored in a read-only section of memory, so you can't modify it.
Given that you're only printing the string with a newline, you can do this instead:
void myprint(char mystring[]){
printf("%s\n", mystring);
}
You are not providing a data type for char_array in
int myprint(char_array)
You need char * or whatever you want it to be.
Firstly, function definitions should be like
return-type function-name ( parameter-type parameter-name, parameter-type parameter-name)
{ ... }
You did not specify either a parameter type or a parameter name. If you mean char_array to mean a type, you need to define it first, using a typedef or a struct or something else. If you mean char_array to be a parameter name, you need to specify its type, as
char[] char_array
say. Also, in this case, you do not actually use the variable char array anywhere in the function myprint. So the argument "sup" is not being used at all.
After edit to the question:
Try
char str[] = "sup";
myprint(str);
instead. As far as I know, you can't pass a string (a character array) by value.
int myprint(char_array)
What type has the parameter with name char_array? Because you didn't specify it, the compiler assumed it to be an int. Luckily it's warning you about that.
Don't rely on such behaviour, though. (I don't know whether this is still legal in C11 for example) Just write correct function declarations, including parameter types.
You need to specify the type of the parameters you expect to be passed to the function. There are mistakes in the function too. char_array is of char* type. You need to copy every part of the passed array to your local array, THEN only can you call printf for this function to work

Simple C Structs: Trouble storing a char * [] into a struct in C. Incompatible types

I am having trouble with a very simple C code in which I need to store an array of char * (Basically, an array of strings) in a struct.
I am getting the error:
error: incompatible types when assigning to type ‘char *[41]’ from type ‘char **’
Here is the relevant code and explanation:
struct HistoryElement
{
int NumberOfCommandGiven;
char * command[MAXLINE/2+1];
};
int main() {
char *args[MAXLINE/2+1];
setup(args); //This gets the command given by user and parses it into args. This works properly.
struct HistoryElement input;
input.command = args; //How to accomplish this without error?
printf("input.command: %s",input.command); //Test
}
The error comes on the line where I am trying to set input.command to args. Although they are both of type char * [], I get the incompatible types error. I am sure this is somewhat simple to fix, but I do not understand what I am doing wrong.
Naked arrays are not assignable. If you want to copy an array, use memcpy or write a manual cycle
#include <string.h>
...
memcpy(input.command, args, sizeof args);
Your "test" does not make sense though. Your input.command is not a string, it is an array of string pointers. You can't just do
printf("input.command: %s", input.command);
on it.

Scanf Seg Fault

I'm working on my assignment for my C course, and I'm trying to take in the user's input and store it in a variable to use for later in my code. Here's what my main function looks like,
int main() {
// Variables here
char* inputLine[10];
do {
printf("Insert number....");
scanf("%s\n", inputLine);
// More stuff here
}
return 0;
}
This code gives me a bunch of warnings, warning: format specifies type 'char *' but the argument has type 'char **' [-Wformat], and if I change the variable declaration to,
char* inputLine = NULL;
When I execute my code I get a seg fault, can someone explain to me what I am doing wrong, and the differences of what happens in the memory when I'm initializing this variable?
char* inputLine[10];
--> is an array of ten pointers to char
printf's format %s expects argument of type char *, but you're providing it as type char **
Just use
char inputLine[10];
To avoid possible buffer overflow you should use
scanf("%9s", inputLine); //Notice the size with %s
9 only because C string are null terminated ('\0') so one extra byte for it goes at end
char inputLine[10];
do {
printf("Insert number....");
scanf("%9s\n", inputLine);
// More stuff here
} while( //some condition);
However if you edit your code and remove * you get answer, but normal array deprecated, nowdays, programmers use vector, normal array in C not safe :
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<string> inputLine;
You can define with every data type:
vector<int> myvar;
Or you can define multidimensional vector:
vector< vector <int> > myvar;

C Function returning an Array

I always thought that when you want to return an array from a function, the only way to do that was using pointers like so:
char * func();
But yesterday, while I was going through K & R, I noticed wrongly assumed that char x()[] is also a valid construct. So I went ahead to test this out and wrote up the following code:
#include <stdio.h>
#include <stdlib.h>
char string1[10] = "123456789";
char x(void)[10];
int main(void) {
printf("string returned by x() is %s",x());
return EXIT_SUCCESS;
}
char x(void)[10] {
return x;
}
Compiling using GCC on Windows, this threw the following errors:
..\src\07arrreturn.c:7:6: error: 'x' declared as function returning an array
..\src\07arrreturn.c: In function 'main':
..\src\07arrreturn.c:10:2: warning: format '%s' expects argument of type 'char *', but argument 2 has type 'int' [-Wformat]
..\src\07arrreturn.c: At top level:
..\src\07arrreturn.c:14:6: error: 'x' declared as function returning an array
..\src\07arrreturn.c: In function 'x':
..\src\07arrreturn.c:15:2: warning: return makes integer from pointer without a cast [enabled by default]
What is happening? am I mis-understanding what the book says? How can you return more than one value (or address) from a function? Isn't that restricted by the fact that you only have a single limited size CPU register that can hold the return value? If you have to return a big chunk of data, you can do so only by returning the address to it right?
Whats the deal with char x()[]? Is such a thing even used?
EDIT: I DID in fact misread the stuff from K&R. See comment below.
char x()[] is also a valid construct
Not as-is, and not quite in this context.
You can use similar syntax to:
declare a pointer to array: char (*arrPtr)[20];
declare an array of function pointers: void (*foo[20])(void);
dereference the return value (pointer) of a function call: char *foo(); char c = foo()[0];
declare a function that returns a pointer to array: char (*foo())[20]
or the same thing with a function pointer: char (*(*foo)())[20]
Which one of these are you looking for?
The C standard (ISO/IEC 9899:2011) says unequivocally:
6.7.6.3 Function declarators (including prototypes)
Constraints
1 A function declarator shall not specify a return type that is a function type or an array
type.
Thus your code is invalid.
K&R C is quite old. In ANSI C (C89), functions returning arrays aren't allowed and what you see is the result of this. First, you get errors for the declaration of x() as a function returning an array and due to this error, x() is never correctly declared and thereby treated like a function returning an int (because this used to be the default return type). This returned int is then supposed to be interpreted as char * generating the final warning.
If you need to return an array, you can wrap it in a struct. Otherwise return a pointer (make sure that the memory it points to is valid after returning).
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char string1[10] = "123456789";
struct ret_s {
char string1[10];
};
struct ret_s x(void);
int main(void) {
struct ret_s r = x();
printf("string returned by x() is %s\n", r.string1);
return EXIT_SUCCESS;
}
struct ret_s x(void) {
struct ret_s r;
strcpy(r.string1, string1);
return r;
}

Resources