Currently in the process of learning a bit of c, but I'm having issues with strings.
I simply want to return a string using a function. This is to be part of a bigger program that's supposed to get the word from an external file, but I want a simple function like this just to get going.
PS. Yes the bigger program is for school. I don't want to simply copy code, i want to understand it. Just throwing that out there.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char* teststring()
{
return (char*)"donald duck";
}
int main()
{
char word[20];
word = teststring();
return 0;
}
I've tried various variations of returning a string, but my problem is that I'm unsure what to use as return type for the function and how to return it.
This is the most common error i get.
[Error] incompatible types when assigning to type 'char[20]' from type 'char *'
I've tried with different return types, declaring and initializing a char array and return it, and my latest test type conversion.
Thanks in advance.
Arrays (more properly, expressions of array type) cannot be the target of an assignment; you cannot copy the contents of one array to another using the = operator.
For strings, you will need to use either the strcpy or strncpy functions:
strcpy( word, teststring() ); // assumes word is large enough to hold the
// returned string.
For other arrays, use memcpy.
You'd better add const modifier to the function teststring() as it returns a pointer to a const string. You cannot reassign word which is the address of char[20] to a pointer that points to a constant string. It must be copied.
#include<string.h>
#include<stdio.h>
const char* teststring()
{
return "donald duck";
}
int main()
{
char word[20];
strcpy(word, teststring());
printf("%s", word);
return 0;
}
Related
I am trying to make an array variable that, inside each position, it has another array in it. My case is the following:
int main() {
char foo[2];
char dummy[3] = {'F', 'O', 'X'};
foo[1] = dummy;
printf("%c", foo[1]);
/* This printf is like a way of saying "show me the 'dummy' list" */
return 0;
}
With this code, i would expect the console to show me the dummy list. Instead, i got a warning that says:
"warning: incompatible pointer to integer conversion assigning to
'char' from 'char [3]' [-Wint-
conversion]"
I dont know if my problem is well understood, but i would like to get an array position like foo[1] to contain another array like dummy, so when i call foo[1] i get that dummy array.
I hope you can help me and thank you in advance for taking your time to help me.
The variable foo that you have defined is a character array of length two but what you want is an array of character pointers. Note that the character array dummy is non-terminated; it is better to leave out the length and initialize it with a string literal instead. Also, to print a string you need to use %s in the call to printf. Try this:
#include <stdio.h>
int main(void)
{
char *foo[2];
char dummy[] = "FOX";
foo[1] = dummy;
printf("%s\n", foo[1]);
return 0;
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I have this code:
char** SplitToWords(char* str);
int main()
{
char** wordarr;
char str[] = "This is a sentence";
wordarr = SplitToWords(str);
return 0;
}
After the main comes the function implementation.
I am not sure the following does what I want it to do (i.e. receive an array of strings from a function):
wordarr = SplitToWords(str);
I somehow managed to convince the compiler that it's ok, but I assume it just does something else.
If it does, how do I find out the length of the array (the number of strings in it).
Thanks
I'll try to quickly visit all aspects you might not yet fully understand:
A string in C is described as a contiguous sequence of chars, ending with a char of value 0 (as a literal: '\0'). It is not a first class object, therefore hasn't its own type. So what you use to hold a string is an array of char. Therefore, taking your question by the word, "receive an array of strings from a function" is not possible.
An array is a contiguous sequence of objects of the same type. In C, the identifier of an array doesn't have a value itself; when it's evaluated, it decays as a pointer to the array's first element instead. This is especially important when passing arrays to functions or returning them from functions -- you can't actually pass the array, you always pass a pointer
e.g. you could write:
char x[] = "foo"; // initialize a char array from a string literal
char *xp = x; // here, x evaluates as a pointer to the first element of the array
You already use pointer types for your function's argument and return value, I just think it's quite important to understand what happens entirely.
You write char** SplitToWords(char* str); and ask whether this returns an "array of strings" -- well, sort of, as you should understand after reading 1. and 2. -- What it does is returning a pointer to char *. This pointer could be a pointer to the first element of an array. So in this case, it would return a pointer to an array of char * pointers. Each of these pointers could itself be a pointer to an array of chars, therefore point to a string. But what's very important is to understand you never return an array, you always return a pointer to it. It's so important because:
You might get the idea to do something like this:
char** SplitToWords(char* str)
{
char *words[16];
// code to fill `words` with pointers to the actual words
return words; // WRONG!
}
Here, because you're not returning the array words but a pointer to it (see point 2), you return a pointer to an object that no longer exists. words is in the scope of your function and has automatic storage duration, that means it only lives as long as the execution is inside of the function. One solution would be to declare words with the static storage class specifier. This way, it lives for the entire execution time of the program. But be aware that this also means there's only a single instance ever, it's always the same object. This will be a major headache for threaded programs, for example. The other way around is to dynamically allocate words using malloc(). But then, the caller of the function must free() it later.
As for your second question, how to let the caller know the number of words -- it's in the comments already, but just for completeness, a typical approach to solve this is to append another entry that is a NULL pointer. So the caller can iterate over the pointers until it finds NULL.
Regarding your comment, of course you can create the array outside the function and pass a pointer to the function, so the function only fills it. This is a common idiom in C (e.g. think about fgets(), which takes a pointer to the char array that's filled with a string by the function).
Functions working this way will need an additional size_t parameter, so they know the size of the array they should fill through the pointer, otherwise you'd have the risk of buffer overflows (this is why gets() was finally removed from the C standard). If you decide that the caller provides the storage, your function should have this prototype:
// returns the number of words found, up to `nwords`
size_t SplitToTwords(char **words, size_t nwords, char *str);
It should be called e.g. like this:
char *words[16];
size_t nwords = SplitToWords(words, 16, "the quick brown fox"); // returns 4
Remember that the strings holding the words themselves need storage as well. You can either manipulate the bytes in str to insert a '\0' after each word, overwriting the first whitespace character (this is what strtok() does) or you can copy the words to new strings, but then you would have to malloc() each of them again and the caller has to free() them later.
Yes, you could solve it by using a function with return value char **. However, there's no way to find out how many words there are afterwards.
You can solve this by allocating one more element for the return pointer and set it to NULL. Then you can get the number of words with this code:
wordarr = SplitToWords(str);
char **ptr=wordarr;
int noWords=0;
while(!*(ptr+noWords))
noWords++;
But if you want to return multiple data in C, you either need to define a return struct or using return arguments. In this case, it could look like this for the first option:
typedef struct wordList {
char **wordarr;
int noWords;
}
wordList SplitToWords(char* str);
And the second:
char** SplitToWords(char* str, int *noWords);
or
void SplitToWords(char* str, char*** wordarr, int *noWords);
Note that there's three *. That's because we want it to be a pointer to char **
#include "stdafx.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXSTRINGS 5000
int main(int argc, char *argv[]) {
char *stringTable[MAXSTRINGS];
char sentence[] = "This is a sentence";
char *token = NULL;
int i = 0;
while ((token = strtok(token == NULL ? sentence : NULL, " ")) != NULL)
{
printf("%s\n\r", token);
stringTable[i] = (char *)malloc(strlen(token) + 1); //have no "plain" C compiler - VS C++ used so cast needed :)
strcpy(stringTable[i++], token);
}
stringTable[i] = NULL; // if you need to iterate through later
printf("%d tokens found\n\r", i);
for (int y = 0; y < i; y++)
free(stringTable[y]);
}
After going through multiple examples of passing a string by value in C, I still don't understand why the following code does not work
int main(void){
char *fileList;
strcpy(fileList,"This is a test line\n");
char type = 'F';
if(checkFileList(fileList, type)){
printf("Proper File list\n");
}
else{
printf("Improper File list\n");
}
}
int checkFileList(char *string, char type){
// Do something with string
}
This program works if I define the variable fileList in the main function as-
char fileList[128];
But I can't provide a fixed size to this string as I get the string only at runtime and hence don't know how long it'll be.
What am I doing wrong here? Please note that I don't want to pass the string by reference as I'll be changing the string in the function and don't want this to be reflected in the original string.
In your code
char *fileList;
strcpy(fileList,"This is a test line\n");
invokes undefined behaviour
, as , fileList is used uninitialized.
You need to allocate memory to fileList before using it. Maybe malloc() and family of functions will help you into that. Also, read about free().
FWIW,
This program works if I define the variable fileList in the main function as-
char fileList[128];
because, the fileList is an array here and the memory allocation is already done by the compiler. So, it is ok to use that.
BTW "Passing string by value" is misuse of the terms. C uses pass-by-value for any function parameter passing.
In order to allocate the memory for the string at runtime you better get to know the size of the string first:
int main(void){
const char *str = "This is a test line\n";
int len = strlen(str);
char *fileList = malloc(len);
// then later you also have to take care for releasing the allocated memory:
free(fileList);
}
First of all I apologize, this is probably a simple question but I'm not very well versed in any coding. For this code, I need to use pointer syntax and define my own function to reverse a string. I'm not allowed to use strlen() in this situation. I've tried playing around with the pointers, but I always get the following errors:
incompatible type when assigning to type char[15] from type char
(I have to write this in pico, so I'm not exactly sure what line number it refers to. It appears to be somewhere around the point I call the strcmp() function
assignment makes integer from pointer without cast
(This one appears to be when I define the s pointer in the function or around there)
Any and all help/troubleshooting ideas would be much appreciated. I'm using a gcc compiler, if that matters
#include<stdio.h>
#include<string.h>
char revcheck(char String[15]);
int main(void)
{
char String[15];
printf("Enter a string: \n");
scanf(" %s", String);
if (strcmp(String, "ENGR-awesome"))
{
printf("That's Right!");
}
else
{
String = revcheck(String);
}
return 0;
}
char revcheck(char String[15])
{
char Letter, *end, *s;
end = strchr(String, '\0');
s = String;
while (end > s)
Letter = &end;
*end = *s;
*s = Letter;
end--;
s++;
return 0;
}
Your revcheck() returns a char. You are trying to assign that to a char[].
You should have your revcheck() return a char*:
char* revcheck(char String[15]);
First you should bear in mind that C-string is an array of chars, and can be represented as char*, a pointer to this array. So, revcheck should not return char. This is the string where the compiler gives the error:
String = revcheck(String);
revcheck can reverse the string in the String array itself (in place) without returning anything. (You can count the len yourself and then swap elements.)
I'm in a basic C programming course and I'm trying to create a hangman game. I've been stuck with a problem for the last three hours and I'm not getting any wiser.
Basically, I've created a function which reads a random line from a text file and then copies it to a string. Afterwards, I want to copy that string to another string outside off the function. This is because the main game is supposed to be completely built with functions.
This is the function that reads a random word from the text file and copies it to a string:
char datorns_val()
{
char ordlista[20];
char valt_ord[20];
int raknare = 0;
srand(time(NULL));
random = rand()%10+0;
ptr_file =fopen("hangman.txt","r");
if (!ptr_file)
{
return 1;
}
while (fgets(ordlista,20, ptr_file)!=NULL)
{
raknare++;
if (raknare == random)
strcpy(valt_ord, ordlista);
}
return valt_ord;
}
After this is done, I want to copy the word located in valt_ord to another string, and that's when I'm unsure about what to do:
char word[20];
strcpy(word,datorns_val());
I'm getting two errors that says:
Invalid conversion from 'char' to 'const char*'
and
initializing argument 2 of 'char* strcpy(char*, const char*)'
Am I on the right track here with using strcpy() twice or am I completely lost? I tried my build without a function structure and simply typing out all the code on after another and it works, if a replace the second strcpy() with a simple char word = valt_ord.
Thanks, Jonathan
(Sorry if my code is hard to understand, I'm swedish and my second language is English)
Currently you're returning a character, which is not of much use, since you need a string that will outlive the function which creates it. You should return a dynamically allocated string (using a pointer) for this.
char* datorns_val()
{
// ... your current code
char *ret_str = malloc(20);
strcpy(ret_str, valt_ord);
return ret_str;
}
At the end where you use it, you should free it when done.
char *result = datorns_val();
// use result
free(result);
result = NULL;
Alternatively, if you're sure that the function which is calling the datorns_val is the only one which is going to use the result, then I'd recommend something else which doesn't involve dynamic memory alloc/decalloc (malloc/free). Pass the string to be loaded to datorns_val.
int datorns_val(char (*str_ptr)[20]) // pointer to an array of 20 chars
{
// use str_ptr after dereferencing it to get back the char array
// say you want to copy "abc" to it
strcpy(*str_ptr, "abc");
return 0; // to denote success, you may return -1 for failure
}
// caller's end
char result[20] = "";
int success = datorns_val(&result); // pass the array by reference
Read more about arrays and pointers to know more about them.
Your function datorns_val is declared to return char while in fact it returns valt_ord that is of type char[]. Also there is a way bigger problem valt_ord is a local variable so even if you change the declaration the code will not work. You will need to allocate valt_ord dynamically(using malloc) or to pass it as function argument.
argument 2 of strcpy needed string but your function returning char.
man strcpy.
you trying to return local variable, it will be destroyed when you move out of function because it stores the data in stack. Use malloc
see this SO question for further clarification