Iterating through pointer character array - c

The function readFile(filename) reads the contents of the file and stores it in heap using malloc, it returns char* datatype. I want to store the content in an array in main so that I can count the words. How do I do so? This is the code:
int main()
{
char *char1;
char1 = readFile("test1.txt");
printf("%s", char1[0]); //This does not print anything
CountWords(*char1, &Alpha, &SentChk, &punct, &Words, &totalSents, &onlyVowel_e);
/*function header of CountWords: void CountWords(char ch, int *Alpha, int *SentChk, int *punct,
int *Words, int *totalSents, int *onlyVowel_e);*/
printf("%d", Words);
printf("%d", totalSents);
return 0;
}

When you call "Countwords", your arguments cant be seen by the main as they arent defined there. Even if you use them in your other funtion - this is a different scope. Maybe you could return a char*[] holding these paramaters you want to return. Or better yet, define all of those arguments in main, have your first function pass them "by reference". This way you have the values put in a place where you can access them later for your "Counwords"

Related

How to pass a struct array to a function

I want to pass a struct array into a function, however, there's something wrong with how I'm passing it and I cant figure out what. I'll include the relevant code.
The Struct:
typedef struct fitbit
{
char patient[10];
} FitbitData;
Main.c:
FitbitData* data = (FitbitData*)malloc(sizeof(data) * 1450);
count = storeToksInArray(line, count, data);
function:
int storeToksInArray(char line[], int count, FitbitData* data[])
{
strcpy(data[count]->patient, strtok(line, ",")); //name
puts(data[count]->patient); }
I've already tested my code and there aren't any problems with line or count. The array works fine in my main file, but once I pass it into the function I can't get it to store the data correctly. The strcpy and puts functions work fine in main as well, so I'm 90% sure it's how I'm passing the array into the function and then using it in the function. I can also use the strtok and puts functions fine by themselves in the function, but once I try storing the token in the array, it doesn't work.
Edit: I figured it out! I removed the brackets after FitbitData data[] to get FitbitData data and then change -> to .**
int storeToksInArray(char line[], int count, FitbitData* data[])
The expression FitbitData* data[] means data is an array of pointers to FitbitData. You seem to be wanting instead a pointer to an array of FitbitData. But an array type is effectively a pointer, so you don't need to pass a pointer to it. Consider changing your function declaration to:
int storeToksInArray(char line[], int count, FitbitData data[])
It appears that data is a FitbitData pointer, and yet your function is expecting an array of FitbitData pointers. Perhaps what you want is either:
int storeToksInArray(char line[], int count, FitbitData* data)
or
int storeToksInArray(char line[], int count, FitbitData data[])
Both are equivalent in this context, it's a question of which you prefer or which seems clearer to you. Personally, I prefer the first one.

Passing struct to function call doesn't work

Since C does not support pass by reference, and I'm developing something that cannot use heap memory, how can I make this work? I want the function call set_var_name to actually change the variables global_log instead of just a local copy. Thanks
#include <stdio.h>
struct Record
{
char type[1];
char var_name[1014];
void* var_address;
char is_out_dated[1];
};
struct Global_Log
{
struct Record records[1024];
int next_slot;
};
void set_var_name(struct Global_Log global_log, int next_slot, char* data, int size)
{
for(int i = 0 ; i < size; i++)
global_log.records[0].var_name[i] = data[i];
printf("%s\n",global_log.records[0].var_name);//here prints out "hello"
}
int main()
{
struct Global_Log global_log;
char a[6] = "hello";
set_var_name(global_log, 0, a, 6);
printf("%s\n",global_log.records[0].var_name); // here prints out nothing
return 0;
}
It seems that you are working with a copy of the struct instance, instead of a reference. Try passing a pointer of a struct as a parameter, so you can work with a reference of the instance:
void set_var_name(struct Global_Log* global_log, int next_slot, char* data, int size)
Another alternative is using a global variable, since it sounds like there won't be another instance of it.
C is a call-by-value language -- when you call a function, all arguments are passed by value (that is, a copy is made into the callee's scope) and not by reference. So any changes to the arguments in the function only affect the copy in the called function.
If you want to call "by reference", you need to do it explicitly by passing a pointer and dereferencing it in the called function.

Functions keep returning 0

I have a three functions one inside another, they use the same inputs as it shown in my code, every time I printf the inputs after I pass the three functions I get a "0" as a value.
I tried to delete the "free()", as I thought it's because of it that my inputs get a 0 as values, but if I do, the code freeze.
char passcode[20];
void configuration(int **d, char *c) {
*d = malloc(sizeof(int));
**d = 1;
readn(*d, c);
return;
}
void readn(int *d, char *c) {
*d = 2;
configuration_SYS(d, c);
return;
}
void configuration_SYS(int *d, char *c) {
strcpy(c, "1234");
*d = 3;
return;
}
void main() {
int *Timeout;
configuration(&Timeout, passcode);
printf("%d\n", *Timeout);
printf("%s", passcode);
}
I expect to get a values different than 0 when I printf the two variables.
Timeout should equal 6 and passcode = "1234".
You do not need to use malloc() every time you use a pointer. malloc() allocates space for your use. NOTE: this space is not necessarily initialized (meaning that the data could be any value)
There is no need to return; at the end of a void function. The closing brace will return for you.
You call configuration_SYS(char* abc, int* d, char* c) with two arguments, yet the function takes three parameters.
As it is, I cannot compile this program. I'm not sure why it prints 0s for you. I would work on creating a Minimal Complete Verifiable Example

How to store result of type char in pointer?

I want to store result of type char in pointer which I'm passing as argument of function. Like this:
#include<stdio.h>
void try(char *);
int main()
{
char *result;
try(result);
printf("%s",result);
return 0;
}
void try(char *result)
{
result="try this";
}
But I'm getting result : (null)
Could someone tell me what's wrong here?
Your syntax only sends the pointer to the function. This allows changing the data the pointer points to, but not the pointer itself.
You would need to have
void try(char **result)
and call it
try(&result);
to change the actual pointer.
Another way is to copy data into the memory pointed by the pointer, but then you need to know there is enough memory available. Depends on the actual use case how to do it properly. You might use
strcpy(result, "what you want");
but then you really have to know that the memory pointed by result can handle 14 chars (remember the NULL in the end). In your current code you don't allocate memory at all for result, so this will invoke undefined behaviour.
The reason you're seeing NULL is because your compiler decided to initialize non-assigned pointers to NULL. Another compiler might initialize them to random values.
Also about terminology, you're not storing type char into a pointer. You may have a pointer pointing to a char, or in this case to a C type string, which is an array of chars.
You are creating another variable result inside try function.
Try printing result inside try function. It will work then.
If you really want to print inside main then try this -
#include<stdio.h>
void try(char **);
int main()
{
char *result;
try(&result);
printf("%s",result);
return 0;
}
void try(char** result)
{
*result = "try this";
//printf("%s\n",result);
}
Or if you don't want to get into double pointers, then this will work:
#include<stdio.h>
char* try(char *);
int main()
{
char *result;
result = try(result);
printf("%s",result);
return 0;
}
char* try(char* result)
{
result = "try this";
return result;
}
Also another way (no dynamic memory):
#include<stdio.h>
void try(char *);
int main()
{
char result[100] = {0};
try(result);
printf("%s",result);
return 0;
}
void try(char *result)
{
strcpy(result,"try this");
}
Note: When you say you got null, that doesn't mean anything - actually you had undefined behaviour there - because result was not initialized. I guess you invoked UB even before trying to print result, namely when you passed it to try. Because copy would be made in that method of the pointer, which would try to read value of original pointer - reading uninitialized variables is undefined in C. Hence always initialize your variables in C.

All the array length methods in C don't work

I have tried (sizeof(array)/sizeof(array[0])). Didn't work.
I wrote a simple function:
int length(int array[]){
int i=0;
while(array[i]) i++;
return i;
}
Worked one minute, didn't work the next.
Someone please help! I'm using Xcode as an IDE
The length of an array is not part of the array in C, so when passing an array as a parameter to a function you should pass its length as a parameter too. Here's an example:
#define ARRLEN(a) (sizeof(a)/sizeof (a)[0]) /* a must be an array, not a pointer */
void printarray(int* a, int alen)
{
int i;
for (i = 0; i < alen; i++)
printf("%d\n", a[i]);
}
main()
{
int a[] = { 3, 4, 5 };
printarray(a, ARRLEN(a));
return 0;
}
However, if your array is defined in such a way as to always end with a sentinel that isn't normal data, then you can traverse the elements until you encounter the sentinel. e.g.,
void printstrings(char** a)
{
int i;
for (i = 0; a[i]; i++)
printf("%s\n", a[i]);
}
main()
{
char* a[] = { "This", "should", "work.", NULL };
printstrings(a);
return 0;
}
Passing an array into a function is the same as passing a pointer to the array.
So sizeof(array)/sizeof(array[0]) does not work.
You can define a global macro:
#define A_LEN(a) (sizeof(a)/sizeof(a[0]))
Try this
main()
{
int a[10] ;
printf("%d\n", sizeof(a)/sizeof(int) ) ;
}
output : 10
See Why doesn't sizeof properly report the size of an array when the array is a parameter to a function? from the comp.lang.c FAQ to understand why the sizeof method doesn't work. You probably should read the entire section on arrays.
Regarding your length function, your "simple" function can work only if your array happens to have the semantic that it is terminated with an element that has the value of 0. It will not work for an arbitrary array. When an array has decayed into a pointer in C, there is no way to recover the size of the array, and you must pass along the array length. (Even functions in the C standard library are not immune; gets does not take an argument that specifies the length of its destination buffer, and consequently it is notoriously unsafe. It is impossible for it to determine the size of the destination buffer, and it therefore cannot prevent buffer overflows.)
There are several methods to get the length of array inside a function (can be in the same file or in different source file)
pass the array length as a separate parameter.
make array length as global extern so that function can directly access global data

Resources