I have a char that is given from fgets, and I would like to know how I can convert it into a char*.
I am sure this has been posted before, but I couldn't find one that was doing quite what I wanted to do. Any answer is appreciated.
EDIT:
Here is the code.
char *filename = "file.txt";
FILE *file = fopen(filename, "r");
if(file != NULL) {
char line[260];
char *fl;
while(fgets(line, sizeof line, file) != NULL) {
// here I combine some strings with the 'line' variable.
str_replace(line, "\"", "\"\""); // A custom function, but it only takes char*'s.
}
printf(fl);
printf("\n");
} else {
printf(" -- *ERROR* Couldn't open file.\n");
}
Well, first of all, line is an array of chars and so can be manipulated in much the same way as a char * (See comp.lang.c FAQs for important differences), so you don't need to worry about it.
However, in case you want an answer to the general question...
The & operator is what you need:
char c;
char *pChar = &c;
However, bear in mind that pChar is a pointer to the char and will only be valid while c is in scope. That means that you can't return pChar from a function and expect it to work; it will be pointing to some part of the heap and you can't expect that to stay valid.
If you want to pass it as a return value, you will need to malloc some memory and then use the pointer to write the value of c:
char c;
char *pChar = malloc(sizeof(char));
/* check pChar is not null */
*pChar = c;
Using the & operator will give you a pointer to the character, as Dancrumb mentioned, but there is the problem of scope preventing you from returning the pointer, also as he mentioned.
One thing that I have to add is that I imagine that the reason you want a char* is so that you can use it as a string in printf or something similar. You cannot use it in this way because the string will not be NULL terminated. To convert a char into a string, you will need to do something like
char c = 'a';
char *ptr = malloc(2*sizeof(char));
ptr[0] = c;
ptr[1] = '\0';
Don't forget to free ptr later!
Related
I am using OpenGL, don't worry my problem is with C and not something related to OpenGL. In OpenGL, we have something called shaders. It is a text file. All I want to do is to read that text file and pass it to a function that accepts only const char * const*. (eg. func(&shaderSource) and shaderSource must be const char* shaderSource.). I just want this terminology with multiple files. Can I? I saw people doing this with C++, but I chose C over C++ in the project. Here is some of my failed attempts.
char vertexShaderContent[1000] = readfile("Shader/default.frag.txt");
const char *vertexShaderSource;
strcpy(vertexShaderSource, vertexShaderContent);
Here I tried to get a new variable (By the way this is in the main function) that executes the function and gets the return value of that function. Now I did copy that string (using strcat) to assign the value of vertexShaderContent to vertexShaderSource. By the way here is my readfile code:
char *readfile(const char* filename) {
char *res = malloc(sizeof(char *) * 100);
char *word = malloc(sizeof(char *));
FILE *file = fopen(filename, "r");
while (fgets(word, sizeof(word), file) != NULL) {
strcat(res, word);
}
strcat(res, "\n\0");
fclose(file);
return res;
}
Summary
All my problem is that I want to pass a char* to a function accepting const char*s. If I can't, is there is any way I can get this 'multiple' files to work?
Thanks.
In char vertexShaderContent[1000] = readfile("Shader/default.frag.txt");, readfile returns a pointer to char, but vertexShaderContent is an array of char. To initialize an array, one needs to provide values for each element to be initialized. A pointer to char is not a correct type for initializing char values.
What may work here is char *vertexShaderContent = readfile("Shader/default.frag.txt");. That defines vertexShaderContent to be a pointer to the memory returned by readfile. However, it is not clear what you want to do, because the code that follows it is confusing:
const char *vertexShaderSource;
strcpy(vertexShaderContent, vertexShaderSource);
This would overwrite the data at vertexShaderContent with new data, so it loses the data that readfile returned. And it attempts to copy from vertexShaderSource, but vertexShaderSource has not been set to point to anywhere. Its value is indeterminate. This strcpy cannot do anything useful. Since we do not know what you are trying to do here, we cannot recommend a solution.
These lines in readfile are incorrect:
char *res = malloc(sizeof(char *) * 100);
char *word = malloc(sizeof(char *));
The first allocates space for 100 char *. To allocate space for 100 char, use char *res = malloc(100 * sizeof *res);.
The second allocates space for one char *. But it looks like you want space for one “word”, which would likely be some varying number of characters. Maybe you would want to start with space for at least 100 characters:
char *word = malloc(100 * sizeof *word);
That could help get the code going at first, although a good eventual solution would ensure the allocated spacer could not be overflowed.
In strcat(res, word), the data pointed to by res has not yet been initialized. Before using strcat, you must have some string in the destination. That can be the empty string, which you can create by putting a null terminator character in res:
*res = '\0';
All my problem is that I want to pass a char* to a function accepting const char*s.
Nothing in the question shows any attempt to pass a char * for a const char * parameter that would not work, except for the issues noted above.
I'm not sure sure about how I should be doing this. This is my code below. The function readLine reads the line from a file and stores it in string though ptr2. I have a feeling im messing up the stars. Could someone please explain to me what would be the right way to do this.
int main(int argc, char **argv)
{
FILE *fp;
fp = fopen("testFile.txt","r");
if( fp == NULL ){
printf("Error while opening the file.\n");
}
char string[75];
char *ptr1 = &string[0]; //want ptr1 to point to string
char *ptr2 = &ptr1[0]; //want ptr2 to point to ptr1
readLine(fp,**ptr2); //want to send ptr2 pointer so that function read the file and add it to string can be edited through the pointer.
printf("%s", **string);
fclose(fp);
return 0;
}
readLine(FILE *fp, char **string){
fgets(**string, 75, fp);
}
Edit: I know there are much better ways of doing this. I have done it this way just to help explain the situation i am trying to understand which is how do pass a pointer to a pointer to a function to edit the string.
If you have char *p1 = &string[0], then you only need to assign the value of p1 to the p2: char *p2 = p1.
I think the asterisks are confusing you. If you have an asterisk in variable declaration, like this: char *p2, it means that variable p2 is a pointer, but when you have asterisk in another place, such as *p2 = 'c', the you dereference the pointer, that is, you save the value of 'c' directly to the memory location where p2 points.
So, here is your code, fixed:
int main(int argc, char **argv)
{
FILE *fp;
fp = fopen("testFile.txt","r");
if( fp == NULL ){
printf("Error while opening the file.\n");
}
char string[75];
char *ptr1 = string;
char *ptr2 = ptr1;
readLine(fp, ptr2);
printf("%s", **pbuff); // I don't know what pbuff is
fclose(fp);
return 0;
}
readLine(FILE *fp, char *string){
fgets(string, 75, fp);
}
Keep in mind that I didn't compile this because I can't right now, using my sister's computer and she is not a programmer. :)
The difficulty you are having, and the question, seems to stem from an unfamiliarity you have with pointers, and how they are passed as parameters to a function. When you declare a character array, e.g. char string[75]; the value held by string is the address to the first character in, (or beginning memory address) for, the statically declared 75-char array. (it itself is a pointer).
When you then declare another pointer to the array, all you need do is assign the value held by string (a pointer to the address of string[0]) to any new pointer created. e.g.:
char *ptr1 = string;
char *ptr2 = ptr1;
It is exactly the same as declaring both pointers and then setting them equal to string, e.g.:
char *ptr1, *ptr2;
ptr1 = ptr2 = string;
When you are dealing with pointers, they are nothing more than a variable that holds the address to something else as their value. Therefore, after the assignment above ptr1, ptr2 and string all hold the same value (that being the address to the first character in the 75-char array).
Now when you pass a pointer as a parameter to a function, the function receives a copy of the pointer, just as a function receives a copy of any other variable. This is important. If the pointer is already declared and allocated (either statically or dynamically), you can simply pass a copy of the pointer and the function will still receive its value (the address of the array). There is no need to pass the address of the pointer in that case, (e.g. char **) passing the pointer itself (even though passed as a copy) its value still provides the needed address of the array.
The only case where you need to pass the address of the pointer are in the cases there the pointer is unallocated (i.e. NULL - holding no address), or where the address of the pointer itself is important (i.e. passing a pointer to a linked-list where you intend to change the first node in the list, etc.) In those cases, then for the calling function to maintain a correct reference to the newly created pointer or the new address for a list (if you delete/add a new first node) -- you must pass the address of the pointer to the function. In your case, that is not required.
In fact, in your case, it doesn't matter which you pass to readLine (ptr1, ptr2, or string) as all hold the exact same value -- the beginning address of an allocated array. You are free to read values using either one, as the characters you read will all be stored beginning at the exact same address.
With that in mind, you could do something similar to the following:
#include <stdio.h>
char *readLine (FILE *fp, char *string);
int main (int argc, char **argv) {
char string[75] = {0};
FILE *fp = NULL;
char *fn = argc > 1 ? argv[1] : "testFile.txt"; /* filename */
char *ptr1, *ptr2;
ptr1 = ptr2 = string;
if (!(fp = fopen (fn, "r"))) { /* validate file open */
fprintf (stderr, "error: file open failed '%s'.\n", fn);
return 1;
}
if (readLine (fp, ptr2))
printf ("%s\n", ptr1); /* any reference to string will work */
else
fprintf (stderr, "error: readLine failure.\n");
fclose(fp);
return 0;
}
char *readLine (FILE *fp, char *string)
{
return fgets (string, 75, fp);
}
Sample Input File
$ cat ../dat/captnjack.txt
This is a tale
Of Captain Jack Sparrow
A Pirate So Brave
On the Seven Seas.
Use/Output
$ ./bin/readln ../dat/captnjack.txt
This is a tale
When you declare:
char string[80];
string IS a pointer to the first element in the array of character.
That being said, I don't understand the roles of both ptr1 and ptr2. You can simple use fscanf if you want to read into a string.
char string[80];
FILE * pFile;
pFile = fopen ("myfile.txt","r");
fscanf (pFile, "%s", string);
You'll need to check the return value of fopen and fscanf of course. Regarding the C function readline, it exists in two places libreadline and libedit. If you are implementing your own readLine, it may also have problems.
Addendum: If you want to modify a string inside a function, say readLine
void readLine(char **arr){
*arr = "efgh";
}
int main(int argc, const char** argv){
char *str = "abcd";
printf("%s\n",str);
readLine(&str);
printf("%s\n",str);
return 0;
}
This passess the address of the pointer str (readLine(&str)), and the pointer itself is changed in the function(*arr = "efgh").
I've got a number of files that I am reading the contents into a char array, I would like to store the contents I read from each file in an array of characters so that I could access the separate character arrays (file contents) by index, I am not sure of the syntax on how to do this.
My understanding is that I need to set each of the memory addresses in my patterns array to one memory address per char array; to the char array stored in patternData but I do not know how to set this. What is the syntax that I am missing that I need to get this to happen?
What I've tried
I would have thought that If I was storing a type of char* then I would need a type char** to store the separate arrays of char arrays.
I would access a char* by using the following notation to set the memory address of the pattern index to
&patterns[INDEX] = &pData;
However this does not work. There is a plethora of "char pointer array" questions but I'm not sure of the correct way to do this simple assignment of pData to an index of patterns.
char *tData;
int tLength;
char *pData;
int pLength;
char **patterns;
void ReadFromFile(FILE *f, char **data, int *length) //This is what is passed into function
int main(int argc, char **argv)
{
for (int i = 1; i <= 5; i++)
{
FILE *f;
char fileName[1000];
sprintf(fileName, "file%d.txt", i);
f = fopen(fileName, "r");
if (f == NULL)
return 0;
ReadFromFile(f, &pData, &pLength); //works to here, contents of file assigned to pData
fclose(f);
&patterns[i - 1] = &pData;
}
return 0;
}
This line is incorrect:
&patterns[i - 1] = &pData;
You are trying to assign to the result of the "take an address" operator, which is not possible because it's not an lvalue.
The assignment should be as follows:
patterns[i - 1] = pData;
but you need to allocate patterns before you do this. You can use
patterns = malloc(sizeof(char*)*5);
or simply declare patterns to be an array of five:
char *patterns[5];
This assumes that your ReadFromFile function allocates a char*, and assigns it to the address pointed to by pData. Note that you need to free all pointers that were obtained through malloc/calloc/realloc.
I haven't read particularly carefully, but it strikes me as odd that you're taking the reference of patterns when it's a **. This is in the line:
&patterns[i-1] = &pData;
I am attempting to grab a title from a text file in a way that is completely new to me. My code is set up as follows:
struct sequence
{ char *name;
char *sequence;
int sequencelen;
};
int main(int argc, char *argv[])
{
struct sequence *newseq;
getsequence("test.txt", newseq);
}
void getsequence(const char *file, struct sequence *seq)
{
FILE *fp = fopen(file, "r");
struct sequence *seqptr = malloc(sizeof(*seq));
char c;
if (!fp)
{
exit(1);
}
while ((c = fgetc(fp)) != "\n")
{
if (c == '>')
continue;
strcat(seqptr -> name, c);
}
printf("Name: %s", seqptr -> name); //Expected output: this_is_a_new_sequence_title
}
The structure for the text file is as follows:
>this_is_a_new_sequence_title
Using structs in this way is, like I said, new to me, but seeing how it is another way to use them I would like to know how to do it. I am unsure, however, if I'm using them correctly, especially with regards to the strcat function.
Do I have to dynamically allocate memory for the struct's member variables, and, if so, how would I go about doing that? Or do I just have everything horribly wrong?
You're never allocating memory for the string. So when you call strcat(), the destination string is uninitialized memory, leading to undefined behavior.
Also, the 2nd argument to strcat() is a string, not a character. That's more undefined behavior as the library function interprets the single character as the address of a string.
You need to initialize storage space for sequence when you allocate it. Also, for code like this (dynamic strings) it's good to separate "allocated room" from "string length", and store both.
Good evening, I have 2 functions and each of them accepts as argument a pointer to char:
char pointer[255];
func1(char* pointer)
{
...
memcpy(pointer,some_char,strlen(something));
return;
}
func2(char* pointer)
{
...
if (pointer==someother_char) exit(0); //FAILs
//also I have
if(pointer==someother_pointer2char); // FAILs
}
Now I've tried strstr,strcmp etc... doesn't work. Wanted to try memcmp but I don't have static len. As I have to compare char* to char and char* to char* I would be needing two solutions right?
So, how to compare these pointers (actually pointees) in shortest possible way?
Thanks.
E D I T
Thanks to wallacer and Code Monkey now for char* to char comparison I use following:
func1(char* ptr){
char someother_char[255];
char *ptr_char = NULL; //I have to strcmp a few values so this is why I initialize it first
...
ptr_char = someother_char;
if (strcmp(ptr,ptr_char) == 0) //gtfo and it does...
...
ptr_char = some2nd;
if(strcmp...
Any suggestions maybe... (hmm external function for comparing?)
Suggestion1(by Code Monkey)
#include <stdio.h>
int main(void) {
char tempchar[255];
tempchar[0] = 'a';
tempchar[1] = 'b';
tempchar[2] = '\0';
char *ptr_char;
ptr_char = &tempchar[0];
printf("%s", ptr_char);
return 0;
}
You need to use strcmp. Not seeing how you tried to use it, this is how you should use it:
char *someother_char = "a";
char *pointer = "a";
if (strcmp(pointer, someother_char) == 0) { // match!
}
else { // not matched
}
to then do the comparison with a char, you have to promote to a char*:
char *someother_char1;
char test = 'a';
char *pointer = "a";
strncpy((char*)test,someother_char1,sizeof(test));
if (strcmp(pointer, someother_char1) == 0) { // match!
}
else { // not matched
}
if you want to use the char array then you have to de-reference:
char char_array[255];
// don't forget to fill your array
// and add a null-terminating char somewhere, such as char_array[255] = '\0';
char *ptr_somechar = &char_array[0];
char *pointer = "a";
if (strcmp(pointer, ptr_somechar) == 0) { // match!
} else { // not matched
}
Well right off the bat, if you want to compare the pointees, you need to dereference them. This means to compare the actual char value, you'll have to call
if (*pointer == someother_char)
However this will only compare the first char in the array, which is probably not what you want to do.
To compare the whole thing strcmp should work
char* someother_str = "hello strstr";
if(strcmp(pointer, someother_str) == 0) {
// do something
}
Make sure your other string is declared as a char*
More info: http://www.cplusplus.com/reference/clibrary/cstring/strcmp/
Edit: as per your comment. comparing char* and char doesn't really make sense. One is a character value, the other is an address in memory. Do do so, you can either dereference the char* or reference the value variable.
char c;
char* ptr;
// dereference ptr
if ( c == *ptr ) {
...
}
// reference the value
if ( &c == ptr ) {
}
The first method checks if the values are the same. The second checks if ptr is in fact pointing to the memory containing c ie. is ptr a pointer to c
Hope that helps
Use function srtncmp no srtcmp.
int res = strncmp(str, "¿Cuál es tu nombre? ", 100);
See the next link
compare strings
Strings are null terminated. When you use such kind of strings, it's not a good idea to mixing with other memory copy functions.
Once you do the memcpy operation, please note that your destination string will not be null terminated.
memcmp is a fast operations. Otherwise yo can simply loop through each character and quit upon finding a difference.
To use strcmp, please make sure that both the strings are null terminated. Otherwise it will lead to some crash.
I suggest you to use string functions like strcmp,strlen, strcpy to deal with strings because for that it's actually implemented.
You can't compare two pointers unless both pointers are referring to same memory location. Pointer is just a address to a memory location. What you really want to do is that, to compare the contents rather than compare the address where it's stored. So please use strcmp but again I warn you make sure that it's null terminated.