Printing Char Array Element - c

I've been hung up on this for the past two hours, and it's really starting to irritate me. I'm using standard C, trying to print a char array's element.
The following is a snippet that works(prints entire array),
CreditCard validate_card(long long n) {
CreditCard cc; // specify new credit card
cc.n = n; // specify card num as passed
cc.valid = false; // initialize as invalid
cc.type = AEX; // initialize at american express
bool valid;
char s[20];
sprintf( s, "%d", n ); // convert credit card number into char array
printf("%s\n", s);
return cc;
}
The following snippet does not work,
CreditCard validate_card(long long n) {
CreditCard cc; // specify new credit card
cc.n = n; // specify card num as passed
cc.valid = false; // initialize as invalid
cc.type = AEX; // initialize at american express
bool valid;
char s[20];
sprintf( s, "%d", n ); // convert credit card number into char array
printf("%s\n", s[0]);
return cc;
}
On that note, if anyone could also too explain to me how to concatinate char array elements to char pointers, I'd be grateful.

When you use this line.
printf("%s\n", s[0]);
The compiler should print some warning about mismatch of the format string %s and the corresponding argument, s[0].
The type of s[0] is char, not char*.
What's your intention?
If you want to print just one character, use:
printf("%c\n", s[0]);
If you want to print the entire array of chracters, use:
printf("%s\n", s);

You need to replace below line
printf("%s\n", s[0]);
with
printf("%c\n", s[0]);
to print 1 character.
To print all characters 1 by 1, use a loop.

If you need to print only the first character of the array, you need to use %c, like
printf("%c\n", s[0]);
Take a look at this MSDN reference

Related

Format "%s" expects and agument of type char* etc, I just want to print the alphabet

Why can't I print the alphabet using this code?
void ft_putchar(char c)
{
write(1, &c, 1);
}
int print_alf(char *str)
{
int i;
i = 0;
while (str[i])
{
if (i >= 'A' && i <= 'Z')
ft_putchar(str[i]);
else
ft_putchar('\n');
i++;
}
return (str);
}
int main ()
{
char a[26];
printf("%s", print_alf(a));
return (0);
}
I get this warning
format ' %s ' expects type 'char*' but argument 2 has type 'int'
How do I print the alphabet using a string, and write function?
Your entire print_alf function looks suspicious.
You are returning str which is of type char *. Therefore the return type of print_alf should to be char * instead of int.
Your while (str[i]) loop makes no sense at all since you are passing uninitialized memory to it. So your code will very likely corrupt the memory since the while loop will continue to run until a '\0' is found within the memory which does not need to be the case within the boundaries of the passed memory (a).
You are not adding a zero termination character ('\0') at the end of the string. This will result in printf("%s", print_alf(a)); printing as many characters beginning at the address of a until a '\0' is found within the memory.
Here is a suggestion how to fix all that problems:
char *print_alf(char *str, size_t len)
{
char letter;
if ((str) && (len >= 27)) // is str a valid pointer and length is big enough?
{
for (letter = 'A'; letter <= 'Z'; letter++) // iterate all characters of the alphabet
{
*str = letter;
str++;
}
*str = '\0'; // add zero termination!!!
}
else
{
str = NULL; // indicate an error!
}
return (str);
}
int main()
{
char a[26 + 1]; // ensure '\0' fits into buffer!
printf("%s", print_alf(a, sizeof(a)));
return (0);
}
Make up your mind whether print_alf should return a string which you then print with printf or whether print_alf should be a void function that does the printing, which you should then just call without printf. At the moment, your code tries to be a mixture of both.
The easiest way is to just print the alphabet:
void print_alf(void)
{
int c;
for (c = 'A'; c <= 'Z'; c++) putchar(c);
}
Call this function like so:
print_alf(); // print whole alphabet to terminal
A more complicated variant is to fill a string with the alphabet and then print that string. That's what you tried to achieve, I think. In that case, you must pass a sufficiently big buffer to the function and return it. Note that if you want to use the string functions and features of the standard lib (of which printf("%s", ...) is one) you must null-terminate your string.
char *fill_alf(chat *str)
{
int i;
for (i = 0; i < 26; i++) str[] = 'A' + i;
str[26] = '\0';
return str;
}
It is okay to return the buffer that was passed into the function, but beware of cases where you return local character buffers, which will lead to undefined behaviour.
You can call it as you intended in your original code, but note that you must make your buffer at least 27 characters big to hold the 26 letters and the null terminator:
char a[27];
printf("%s\n", fill_alf(a));
Alternatively, you could do the filling and printing in twp separate steps:
char a[27];
fill_alf(a); // ignore return value, because it's 'a'
printf("%s\n", a); // print filled buffer
If you just want to print the alphabet, the print_alf variant is much simpler and straightforward. If you want to operate further on the alphabet, eg do a shuffle, consider using fill_alf.
Your print_alf(char *str) function actually returns an integer which causes the error (it is defined to return int). When you specify %s to printf it expects characters, not numbers.
You can fix this by changing the return type of your function to char and if everything else works in your code you'll be good to go.

Using Pointers and strtok()

I'm building a linked list and need your assistance please as I'm new to C.
I need to input a string that looks like this: (word)_#_(year)_#_(DEFINITION(UPPER CASE))
Ex: Enter a string
Input: invest_#_1945_#_TRADE
Basically I'm looking to build a function that scans the DEFINITION and give's me back the word it relates to.
Enter a word to search in the dictionary
Input: TRADE
Output: Found "TREADE" in the word "invest"
So far I managed to come up using the strtok() function but right now I'm not sure what to do about printing the first word then.
Here's what I could come up with:
char split(char words[99],char *p)
{
p=strtok(words, "_#_");
while (p!=NULL)
{
printf("%s\n",p);
p = strtok(NULL, "_#_");
}
return 0;
}
int main()
{
char hello[99];
char *s = NULL;
printf("Enter a string you want to split\n");
scanf("%s", hello);
split(hello,s);
return 0;
}
Any ideas on what should I do?
I reckon that your problem is how to extract the three bits of information from your formatted string.
The function strtok does not work as you think it does: The second argument is not a literal delimiting string, but a string that serves as a set of characters that are delimiters.
In your case, sscanf seems to be the better choice:
#include <stdlib.h>
#include <stdio.h>
int main()
{
const char *line = "invest_#_1945 _#_TRADE ";
char word[40];
int year;
char def[40];
int n;
n = sscanf(line, "%40[^_]_#_%d_#_%40s", word, &year, def);
if (n == 3) {
printf("word: %s\n", word);
printf("year: %d\n", year);
printf("def'n: %s\n", def);
} else {
printf("Unrecognized line.\n");
}
return 0;
}
The function sscanf examines a given string according to a given pattern. Roughly, that pattern consists of format specifiers that begin with a percent sign, of spaces which denote any amount of white-space characters (including none) and of other characters that have to be matched varbatim. The format specifiers yield a result, which has to be stored. Therefore, for each specifier, a result variable must be given after the format string.
In this case, there are several chunks:
%40[^_] reads up to 40 characters that are not the underscore into a char array. This is a special case of reading a string. Strings in sscanf are really words and may not contain white space. The underscore, however, would be part of a string, so in order not to eat up the underscore of the first delimiter, you have to use the notation [^(chars)], which means: Any sequence of chars that do not contain the given chars. (The caret does the negation here, [(chars)] would mean any sequence of the given chars.)
_#_ matches the first delimiter literally, i.e. only if the next chars are underscore hash mark, underscore.
%d reads a decimal number into an integer. Note that the adress of the integer has to be given here with &.
_#_ matches the second delimiter.
%40s reads a string of up to 40 non-whitespace characters into a char array.
The function returns the number of matched results, which should be three if the line is valid. The function sscanf can be cumbersome, but is probably your best bet here for quick and dirty input.
#include <stdio.h>
#include <string.h>
char *strtokByWord_r(char *str, const char *word, char **store){
char *p, *ret;
if(str != NULL){
*store = str;
}
if(*store == NULL) return NULL;
p = strstr(ret=*store, word);
if(p){
*p='\0';
*store = p + strlen(word);
} else {
*store = NULL;
}
return ret;
}
char *strtokByWord(char *str, const char *word){
static char *store = NULL;
return strtokByWord_r(str, word, &store);
}
int main(){
char input[]="invest_#_1945_#_TRADE";
char *array[3];
char *p;
int i, size = sizeof(array)/sizeof(char*);
for(i=0, p=input;i<size;++i){
if(NULL!=(p=strtokByWord(p, "_#_"))){
array[i]=p;//strdup(p);
p=NULL;
} else {
array[i]=NULL;
break;
}
}
for(i = 0;i<size;++i)
printf("array[%d]=\"%s\"\n", i, array[i]);
/* result
array[0]="invest"
array[1]="1945"
array[2]="TRADE"
*/
return 0;
}

segmentation fault while running the programme

I have written code for parsing a string into words. Here is code. Can any one help here to fix the segmentation fault error during run time?
Calling fun :
int main()
{
int count = 0, i; // count to hold numbr of words in the string line.
char buf[MAX_LENTHS]; // buffer to hold the string
char *options[MAX_ORGS]; // options to hold the words that we got after parsing.
printf("enter string");
scanf("%s",buf);
count = parser(buf,options); // calling parser
for(i = 0; i < count; ++i)
printf("option %d is %s", i, options[i]);
return 0;
}
Called function:
int parser(char str[], char *orgs[])
{
char temp[1000];//(char *)malloc(strlen(str)*sizeof(char));
int list = 0;
strcpy(temp, str);
*orgs[list]=strtok(str, " \t ");
while(((*orgs[list++]=strtok(str," \t"))!=NULL)&&MAX_ORGS>list)
list++;
printf("count =%d",list);
return list;
}
Note : I'm trying to learn C these days, can any one help to get a good tutorial (pdf) or site to learn these strings with pointers, and sending string to functions as arguments?
You are using strtok wrong.
(It is generally best to not use strtok at all, for all its problems and pitfalls.)
If you must use it, the proper way to use strtok is to call it ONCE with the string you want to "tokenize",
then call it again and again with NULL as an indication to continue parsing the original string.
I also think you're using the orgs array wrong.
Change this assignment
*orgs[list++]=strtok(str, " \t ");
to this:
orgs[list++]=strtok(str, " \t ");
Because orgs is an array of character-pointers.
orgs[x] is a character-pointer, which matches the return-type of strtok
Instead, you are referring to *orgs[x], which is just a character.
So you are trying to do:
[character] = [character-pointer];
which will result in "very-bad-thingsā„¢".
Finally, note that you are incrementing list twice each time through your loop.
So basically you're only filling in the even-elements, leaving the odd-elements of orgs uninitialized.
Only increment list once per loop.
Basically, you want this:
orgs[list++] = strtok(str, " \t ");
while(( (orgs[list++] = strtok(NULL," \t")) !=NULL) && MAX_ORGS > list)
/* do nothing */;
PS You allocate space for temp, and strcpy into it.
But then it looks like you never use it. Explain what temp is for, or remove it.
char buf[MAX_LENTHS];
You have not defined the array size, i. e. MAX_LENTHS should be defined like
#define MAX_LENTHS 25
And as Paul R says in his comment you also need to initialize your array of character pointers
char *options[MAX_ORGS];
with something .
int parser(char str[], char *orgs[]){
int list=0;
orgs[list]=strtok(str, " \t\n");
while(orgs[list]!=NULL && ++list < MAX_ORGS)
orgs[list]=strtok(NULL," \t\n");
printf("count = %d\n",list);
return list;
}
int main(){
int count=0,i;
char buf[MAX_LENTHS];
char *options[MAX_ORGS];
printf("enter string: ");
fgets(buf, sizeof(buf), stdin);//input include space character
count=parser(buf,options);
for(i=0;i<count;++i)
printf("option %d is %s\n",i,options[i]);
return 0;
}

String slicing in array prints two characters?

The C program below print the first and last character of 16 words strings:
#include<stdio.h>
#include<string.h>
void main()
{
char first, last;
char *str = "abcdefghijklmnop";
first = str[0];
last = str[15];
printf("%s", &first);
printf("%s", &last);
}
The output I am seeking is a and p. But, when I run this code I get the output:
apa
What am I doing wrong?
You're missing understanding of pointers. When you assign a character to first and last, then those characters will essentially be copied to first and last. Since first and last are distinct variables, their addresses have no relation to the char *str pointer. Also, printf("%s", &first); (and the same with last) invokes undefined behaviour, since printf expects a 0-terminated string, but you pass one character only, after which there's no zero terminator.
What you can do is either use pointers:
char *first = str + 0;
char *last = str + 15;
printf("%s %s", first, last);
This will print abcdefghijklmnop p
or to print the two chars only:
char first = str[0];
char last = str[15];
printf("%c %c", first, last);
This will print a p.
below lines will bring correct result
printf("%c", first );
printf("%c", last );
Your variables first and last are actual character values, not strings/pointers. You need to use %c instead. Try:
#include<stdio.h>
#include<string.h>
void main()
{
char first, last;
char *str = "abcdefghijklmnop";
first = str[0];
last = str[15];
printf("%c", first);
printf("%c", last);
}
The %s expects to get a pointer that points to an array of character values and keeps reading until it reaches a NULL character \0.
You can read more about this here http://pw1.netcom.com/~tjensen/ptr/ch3x.htm and here http://www.codingunit.com/printf-format-specifiers-format-conversions-and-formatted-output.
I find that the following C++ page has a better diagrams for visualizing pointers http://cplusplus.com/doc/tutorial/pointers/.

How do I set the number of characters output in a fprintf '%s' format using a variable?

I need to write a variable number of characters to a file. For example, lets say I want to print 3 characters. "TO" would print "TO" to a file. "LongString of Characters" would print "Lon" to a file.
How can I do this? (the number of characters is defined in another variable). I know that this is possible fprintf(file,"%10s",string), but that 10 is predefined
This one corresponds to your example:
fprintf(file, "%*s", 10, string);
but you mentioned a maximum as well, to also limit the number:
fprintf(file, "%*.*s", 10, 10, string);
I believe you need "%*s" and you'll need to pass the length as an integer before the string.
As an alternative, why not try this:
void print_limit(char *string, size_t num)
{
char c = string[num];
string[num] = 0;
fputs(string, file);
string[num] = c;
}
Temporarily truncates the string to the length you want and then restores it. Sure, it's not strictly necessary, but it works, and it's quite easy to understand.
As an alternative, you may create "c_str" from your buffer and prepare string to printf like I do that in this source:
void print(char *val, size_t size) {
char *p = (char *)malloc(size+1); // +1 to zero char
char current;
for (int i=0; i < size; ++i) {
current = val[i];
if (current != '\0') {
p[i] = current;
} else {
p[i] = '.'; // keep in mind that \0 was replace by dot
}
p[i+1] = '\0';
}
printf("%s", p);
free(p);
}
But it solution wrong way. You shuld use fprintf with format "%*s".

Resources