For example,
#include <stdio.h>
int main (int argc, const char * argv[]) {
char out = printf("teststring");
printf("%d\n", out);
return 0;
}
will return teststring10. Anyone has an idea how to get rid of the 10?
Thanks in advance.
Lets look at your code:
#include <stdio.h>
int main (int argc, const char * argv[]) {
char out = printf("teststring");
printf("%d\n", out);
return 0;
}
And change it:
#include <stdio.h>
int main (int argc, const char * argv[]) {
const char *str = "teststring";
int out = printf("%s", str);
printf("\nPrintf wrote %d bytes when printing %s\n", out, str);
return 0;
}
Compile / run the edited version and you should immediately see the difference. Modify the length of str then compile and run it again.
Now, just a tiny change to your original code:
#include <stdio.h>
int main (int argc, const char * argv[]) {
char out = printf("teststring\n");
printf("%d\n", out);
return 0;
}
You can see now, you are printing two different things, and out has become 11, since a newline was added. Nothing is actually trailing here. Then change %d to %c (the correct format specifier for out in your example) and notice the difference. ASCII (11) is a vertical tab (see here). YTMV (your terminal may vary). Here, you printed a character, not a character representation of an integer.
The actual type that printf() returns is int, which is an integer. The reason for this is so that you know exactly how many bytes printf() actually printed. This typical for that family of functions, but more useful for functions like snprintf() so you can know if it could not print the entire length of any given format to a buffer. Note that the return type is signed, it can be negative, so the storage type you pick to store its value matters quite a bit, especially if you work with that value while assuming that its greater than or equal to zero.
Here is a handy tutorial to format specifiers you can use with the printf() family of functions. More importantly, check the return type of the functions that you are using.
I also suggest spending some quality time with this book, be sure to work through the exercises as time permits. Its the best self-study course in C and the exercises are fun. When you get a solid grasp of C, work through the exercises again .. then compare your answers, its eye opening :)
the 10 is because of the
printf("%d\n", out);
printf return the number of characters written to the output stream
the length of "teststring" which is 10 assigned to "out"
and the n you print the value of out - so 10 is printed.
int main(int argc, char *argv[])
{
const char *str = "This is a constant string";
printf("%s\n", str);
return 0;
}
%s is the format specifier for a string. %d is the format specifier for a decimal representation of an integer. printf will return the number of characters written to the output.
#include <stdio.h>
int main (int argc, const char * argv[]) {
char out = printf("teststring");
printf("%d\n", out);
return 0;
}
Assuming that you want to assign "out" to a function (as I think you've said somewhere):
#include <stdio.h>
int main (int argc, const char * argv[])
{
char *out = NULL;
out = funcReturns("teststring");
printf("%s\n", out);
return 0;
}
If you allocate the memory inside the function that returns "teststring" then I think you need to make the return value static. For example (code untested):
char *funcReturns(char *returnStr)
{
static char *returnThis = NULL;
returnThis = strdup(returnStr);
return returnThis;
}
int printf ( const char * format, ... );
On success, the total number of characters written is returned.
When you execute this:
char out = printf("teststring");
The string "teststring" will be printed on your screen, and the value 10 will be
atrib to variable out.
Notice that the print cursor will be kept on the current line at the end of "teststring", once you did not put sufix '\n' on the end of string.
So, when you execute printf("%d\n", out); on the next line, the program will print the value 10 just after "teststring", and you will see "teststring10 on your screen."
If you really want to get rid of the 10 just remove the line printf("%d\n", out); from your code...
int main (int argc, const char * argv[]) {
int out = printf("teststring\n");
/* printf("%d\n", out); */
return 0;
}
Related
I've been trying to code a really simple string to morse code converter in C for a few hours now and I finally got it to compile without any warnings. I'm a beginner in C so I really cannot understand how to fix my code. I believe the problem should be in how I pass strings around with pointers and etc, since this is the part I do not understand the most. I found an example on how to do it, but I still couldn't understand it, and there wasn't any specific case that would be similar to mine, since I want it to read strings from the arguments (all arguments are strings/words).
And now I'm getting a segmentation fault when trying to run it:
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int to_morse(char *);
int main(int argc, char **argv)
{
char morse[80];
char *temp;
for (int counter = 1; counter < argc; counter++)
{
*temp = to_morse(argv[counter]);
strcat(temp, morse);
printf("%s", morse);
}
return 0;
}
int to_morse(char *str)
{
char *morse[27] = {".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--.."};
char *output;
char character;
for (int counter = 0; str[counter] != '\0'; counter++)
{
character = toupper(str[counter]);
strcat(morse[character-'A'], output);
}
return *output;
}
I believe this is not a correct way to pass around strings using pointers, but I cannot figure out the right way. How would I be able to make my code work?
Note: I'm aware this might have a duplicate somewhere.. however, there are tons of segmentation fault questions and all of them are really specific and do not cover my scenario, so I couldn't find one.
There is so much going wrong with your code.
Firstly, strcat takes 2 parameters - a destination and then a source. In all cases that you're using it, you've got them the wrong way around.
Secondly, your function to_morse returns an int when you want it to return a char *. That would be how you pass around pointers.
Thirdly, you don't allocate any memory for output in that function, so even if you had the strcat the right way around, you've not got anywhere to store the morse code. That'll also be where the code is crashing as you're passing in an uninitialised pointer to strcat.
Finally, you should probably check that the character you're trying to convert to morse is a letter, otherwise you'll go out of bounds on your array.
Here is how your code should look. I've also tweaked it so that you put a space between each morse "letter" as otherwise you'd not be able to tell where one begins and another ends.
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
char *to_morse(char *);
int main(int argc, char **argv)
{
char *temp;
for (int counter = 1; counter < argc; counter++)
{
temp = to_morse(argv[counter]);
printf("%s", temp);
free(temp); // Always remember to free memory you allocate
}
return 0;
}
char *to_morse(char *str)
{
char *morse[27] = {".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--.."};
char *output=malloc((strlen(str)*5)+1); // Always remember to allocate 1 more char than you need to store the NUL terminate when allocating memory for strings.
output[0] = '\0'; // strcat need a null terminator in the string.
char character;
for (int counter = 0; str[counter] != '\0'; counter++)
{
if(isalpha(str[counter]))
{
character = toupper(str[counter]);
strcat(output,morse[character-'A']);
strcat(output," ");
}
}
return output;
}
I don't fully understand how to work with pointers.
Inside the function is where I need to write code to return the length of input string.
int mystrlen (const char *s)
{
char *s[1000], i;
for(i = 0; s[i] != '\0'; ++i);
printf("Length of string: %d, i");
return 0;
}
Could you tell me how to make it work?
Thank you!!
Remove char *s[1000], declare int i instead of char i, and return i rather than 0:
You need to remove the s inside the function body because it is "shadowing the variable" s that is a function parameter, meaning the s function parameter cannot be read at all.
Changing char i to int i will likely increase the range of possible values to return. If you pass a string with 128 characters in it, char i would result in returning -128 if it is a signed 8-bit type. int is guaranteed to be 16-bit, allowing for strings up to 32767 characters (more than enough for most common uses of a string length function).
You return i because otherwise the function is pointless; even if you print the value, you'd need a way to use the string length, and you can't do that if you don't return it from the function.
Corrected code with example:
#include <stdio.h>
int mystrlen(const char *s)
{
int i;
for (i = 0; s[i] != '\0'; ++i);
return i;
}
int main(void)
{
const char *s = "Hello world!";
int len = mystrlen(s);
printf("Length of string: %d\n", len);
return 0;
}
First of all, using pointers, as the number says, consist in using a reference instead of the actual variable, so if you pass a reference by parameter, you are not passing the actual value of it, just an address to it!
The correct code is:
#include <stdio.h>
int mystrlen (const char *s)
{
int i;
for( i = 0; s[i] != '\0'; ++i);
printf("Length of string: %d\n", i);
return 0;
}
void main(){
char *string = "Hello World";
mystrlen(string);
}
Another thing to point out is that you're trying to declare a const variable and change it. When you declare a const variable it should not change.
Question: Write a program anagram that sorts the letters in a word, which is useful when searching for anagrams. anagram takes a single argument, which is a string containing only lower-case letters, sorts the letters alphabetically, and then prints the sorted letters. You may use any sorting algorithm you are familiar with, but you must write the sort function yourself. You may not use any sort function provided by a library.
Usage
$ ./anagram hello
ehllo
$ ./anagram positivity
iiiopsttvy
$ ./anagram abcdef
abcdef
The below code is what I have done so far but I get the error
passing char * to parameter of unsigned char converts between pointers to integer types with different sign
#include <stdio.h>
#include <string.h>
void anagram(unsigned char input[])
{
int count[256] = { 0 };
int i;
for (i = 0; input[i] != '\0'; i++)
{
count[input[i]]++;
}
for (i = 0; i < 256; i++)
{
while (count[i] > 0)
{
printf("%c", i);
count[i]--;
}
}
}
int main(int argc, char* argv[])
{
if(argc > 1)
{
anagram(argv[1]);
}
return 0;
}
The short answer to your question is you are getting the pointer sign mismatch warning because you are attempting to pass argv[1] (type char *) to anagram which you have declared with a parameter of unsigned char * (though you use input[], the practical effect is that input decays to a pointer when used as a parameter)
The simple solution while preserving the unsigned char* type for anagram is to cast argv[1] to (unsigned char *) when passed as a parameter to anagram, e.g.
anagram((unsigned char *)argv[1]);
The more practical question is "Do you really need the unsigned char* type to begin with?" While you can escape and pass non-ASCII values as the argument to your program -- is that something you expect and want to protect against by using the unsigned char* (which is 100% fine to do).
Generally, you would simply declare anagram (char *input) (which is your second alternative to eliminate the signed mismatch on the pointers) and limit your loop to looping over the valid range for ASCII characters (see ASCIItable.com)
Either way is fine so long as you handle the pointer signedness consistently. Putting that altogether and removing the magic numbers from your code, you could do something similar to the following:
#include <stdio.h>
#include <string.h>
#define CHRSET 256 /* if you need a constant, define one */
void anagram (unsigned char *input)
{
int i, count[CHRSET] = { 0 };
for (i = 0; input[i] != '\0'; i++)
count[input[i]]++;
for (i = 0; i < CHRSET; i++)
while (count[i] > 0) {
printf("%c", i);
count[i]--;
}
putchar ('\n'); /* provide a POSIX compliant newline before termination */
}
int main(int argc, char *argv[]) {
if (argc < 2) {
fprintf (stderr, "error: insufficient input\n"
"usage: %s <string>\n", argv[0]);
return 1;
}
anagram ((unsigned char *)argv[1]);
return 0;
}
(note: you can also move the output of the final newline to main, but unless you plan on smushing multiple sorted strings together by making repeated calls to anagram, then it is better left after the output of each string)
Look things over and let me know if you have further questions.
I'm new in c programming and I want to pass array from library.
I have function in library c file that creates char array. How to use this array in main function. This is short code of something I tried:
libfile.c
char *myArray;
void PopulateArray()
{
// Getting data from serial port in char buffer[100]
myArray = buffer;
}
libfile.h
exter char *myArray;
void PopulateArray();
program.c
int main()
{
// in fore loop
printf("%s\n" , myArray[i]);
}
This is just one of combinations that I have tried but nothing works.
How to do this?
To pass an array from a library function to the surrounding code, you can use the return value of a function or use a pointer-to-pointer argument.
See the following example code.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* createSourceCopy() {
const char *source = "Example Text";
// We got some text in variable source;
const size_t sourceSize = strlen(source);
char *result = (char*)malloc(sizeof(char)*(sourceSize+1));
strncpy(result, source, sourceSize);
return result;
}
A user of your library could use the function like this:
main() {
char *result = createSourceCopy();
// Do something with result.
// After the use, destroy the array
delete[] result;
return 0;
}
Another way how to pass an array is this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
bool copySourceText( char **outText ) {
const char *source = "Example Text";
// We get some text in variable source;
const size_t sourceSize = strlen(source);
*outText = new char[sourceSize];
strncpy(*outText, source, sourceSize);
return true; // success
}
This second variant has the benefit that the return value can be used as status. The function could return true on success, or false if there was an error.
This second version can be used like this.
int main() {
char *result;
if (copySourceText(&result)) {
// Do something with result.
// After the use, destroy the array
free(result);
result = NULL;
} else {
// Error handling
}
return 0;
}
It's not clear exactly what's going wrong in the code you posted (it would help to see more code), but assuming your problem isn't a compilation error, one of these lines might be wrong:
char *myArray;
printf("%s\n" , myArray[i]);
char *myArray declares a pointer to char (which would be appropriate for a single string).
The printf line dereferences myArray (producing a char, i.e. one character). You're passing down a char, but the %s format expects a pointer-to-char.
If you want to print the string character-by-character, you could use %c:
for (i = 0; i < length; i++) {
printf("%c\n", myArray[i]); /* or %x or %d if you want */
}
Otherwise, if myArray is one string and is null-terminated (see Why is a null terminator necessary?), then you could do:
printf("%s\n" , myArray); /* [i] removed, no for loop necessary */
In this program, i want to let user to input 2 arguments, the number
of integer,and the file name.
the file has 10 lines of integer value.
read the file, and put it to inArray[];
and then output it as the end;
notes: For the complete program, i want to make a program that
will scan a file consists of random integer,and then sort
them in ascend order, and print out the first 10 percent
of the sorted integer.
Error: For now, i want to test if it can read the file and put values
into the inArray properly, but its keep getting errors.
warning: initialization makes integer from pointer without a cast
findTotal.c:43:6: warning: passing argument 1 of ‘fopen’
makes pointer from integer without a cast
/usr/include/stdio.h:271:14: note: expected ‘const
char * __restrict__’ but argument is of type ‘char’
Please help me with this, thank you
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char *argv[]){
int numOfInt;
char fileName="";
sscanf(argv[1],"%d",&numOfInt);
sscanf(argv[2],"%c",&fileName);
int i, rc;
/* the origninal list , initialise as 0 index*/
int inArray[numOfInt];
/* the number of output int */
int outNumInt = numOfInt * 0.1;
/* the output array of int */
int outArray[outNumInt];
FILE *inFile;
inFile = fopen(fileName,"r");
/* check if the file is empty */
if(inFile==NULL){
printf("can not open the file");
}
for (i = 0; (rc = getc(inFile)) != EOF && i < numOfInt; inArray[i++] = rc)
{
}//for
fclose(inFile);
for(i = 0; i < numOfInt;i++){
printf("%x\n",inArray[i]);
}
}//main
I think you could be using scanf better here. You use it to read in two pieces of information that should have been passed as arguments to the program, and then refreain from using it for what it would actually be good for, which is reading the file in question. Here is my take at this:
#include <stdlib.h>
#include <stdio.h>
int cmp(const void *a, const void *b) { return *(int*)b - *(int*)a; }
int main(int argc, char *argv[])
{
char * ifile = argv[1];
int n = atoi(argv[2]), m = n/10, i;
int nums[n];
FILE * f = fopen(ifile, "r");
for(i = 0; i < n; i++) fscanf(f, "%d", &nums[i]);
qsort(nums, n, sizeof(int), cmp);
for(i = 0; i < m; i++) printf("%d\n",nums[i]);
return 0;
}
If this file is prog.c and the corresponding executable is prog, and your file with numbers is called nums.txt, and contains 100 integers, you would call this as
prog nums.txt 100
The advantage of taking in parameters this way is that it makes repeating the command later easier (all the information needed to repeat it will be in the command history of the shell), and that it is the standard way of passing parameters to a program. It also frees up standard input for other uses.
You have indeed a problem with the filename's management. char is for characters; if you want to handle a file name, you have to use a string. In C, we can use an array of char, terminated by a nul-character. Here, because argv[2] holds directly the name, you can simply use a pointer.
char *fileName = argv[2];
And then:
fopen(fileName, "r");
Since you don't modify the argv pointer, you can also send directly argv[2] as argument.
One of the problems I see in your code is:
char fileName="";
sscanf(argv[2],"%c",&fileName)
A string literal is a constant string, which means you shouldn't attempt to modify it, you should either use a static (or dynamic) char array for that string and use the %s format specifier, or just point fileName to argv[2]
char *fileName;
fileName = argv[2];