printing a string in c characer by character - c

i know , that my question is unusual behaviour for coding , but i just do it , to understand C language in deep , so i ask user to enter a string and i want to print this string character by character , before doing this , i save the string in memory , which it's address saved in 'x' , can i print this string character by character , by this way ?
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(int argc ,char *argv[20])
{
char x ;
strcpy(&x,argv[1]);
printf("%s and it's length is %d : \n" , &x , strlen(&x));
int i ;
for(i=0 ; i < strlen(&x) ; i++)
{
printf(" hi : %c\n" , x[i]);
/* also i try '%x[i]' but it's give me another error
so how i do this ??*/
}
return 0;
}

The basic idea is correct, but there are some problems in the code.
x is only a single character. You´ll need an array of it.
Then replace every &x with x, because the array pointer itself is already an address.
And another thing: char *argv[20].
Why 20? Why not char *argv[] ?

So, starting from the beginning:
int main(int argc ,char *argv[20])
^^^^
This does nothing; whenever you declare a function parameter as T a[N] or T a[], it's intepreted as T *a; the traditional way to write this is as either
int main( int argc, char *argv[] )
or
int main( int argc, char **argv )
The second case more accurately reflects what's really happening; argv is a pointer to a sequence of pointers to char. The value of argv[argc] is NULL.
{
char x ;
strcpy(&x,argv[1]);
This is a problem; by declaring x as char, you've only set aside enough storage to hold a single character value1, but you're trying to use it to store an array of character values; that isn't going to work, and you're going to wind up clobbering whatever memory immediately follows x, which may or may not lead to a crash. C doesn't do any bounds checking for you; when you give strcpy an address, it will happily copy the given string to the storage following that address without making sure that storage is valid.
You have two options at this point: you can either declare x as an array of char:
char x[SOME_SIZE]; // where SOME_SIZE is large enough to handle your
// largest expected input
and use strcpy as follows:
strcpy( x, argv[1] );
or you can simply declare x as a pointer to char:
char *x;
and assign it to point to the beginning of argv[1]:
x = argv[1];
Either way, the rest of the code becomes
printf("%s and it's length is %d : \n" , x , strlen(x)); // no & before x
int i ;
for(i=0 ; i < strlen(x) ; i++)
{
printf(" hi : %c\n" , x[i]);
}
return 0;
}
Note that a much simpler way of doing this would be
int main( int argc, char **argv )
{
char *p = argv[1];
if ( p ) // argv[1] is not NULL
{
while ( *p ) // argv[1][i] is not 0
printf( "hi: %c\n", *p++ );
}
return 0;
}
1. Which is why x[i] wasn't working for you, since x is not an array or pointer expression

deviantfan is right that you are overwriting something in memory that does not belong to the variable. Here is one of the ways to accomplish your task without any memory-editing voodoo:
#define ARGV_SIZE 20
int main(int argc ,char *argv[ARGV_SIZE])
{
char x[ARGV_SIZE];
int argvLength;
strcpy(x, argv[1]);
argvLength = strlen(x);
printf("%s and it's length is %d : \n" , x , argvLength);
for (int i = 0 ; i < argvLength; i++)
{
printf(" hi : %c\n" , x[i]);
}
return 0;
}
or without the x variable you can do this:
int main(int argc ,char *argv[])
{
int argvLength = strlen(argv[1]);
printf("%s and it's length is %d : \n" , argv[1] , argvLength);
for (int i = 0 ; i < argvLength; i++)
{
printf(" hi : %c\n" , argv[1][i]);
}
return 0;
}

try this
#include<stdio.h>
#include<string.h>
int main(int argc ,char *argv[20]){
char y = 'Y';
char x ;
char z = 'Z';
strcpy(&x, "This program is correct!!!");
printf("%s and it's length is %d : \n" , &x , strlen(&x));
printf("%c%c%c", x,y,z);//print TYZ ?
return 0;
}

Related

puts() not printing out string in main() but prints fine in function

#include <stdio.h>
#include <string.h>
void mergeStr(char *a, char *b, char *c);
int main()
{
char a[80],b[80];
char c[80];
printf("Enter the first string: \n");
gets(a);
printf("Enter the second string: \n");
gets(b);
mergeStr(a,b,c);
printf("mergeStr(): ");
puts(c);
return 0;
}
void mergeStr(char *a, char *b, char *c)
{
int size; int i ; int j=0 ; // again, forgot to initialize j
char ch;
char temp[80] ;
/* Merge string a and string b together, then sort them alphabetically */
c = strcat(a,b) ;
size = strlen(c) ;
for (ch = 'A' ; ch <= 'z' ; ch++ ) { // iterates from A-Z and a-z
for (i=0 ; i<size ; i++) { // which for loop comes first is important, in this case since we want duplicates we should allow i to iterate everything for every case of ch
if (c[i] == ch){
temp[j] = c[i] ;
j++ ;
}
}
}
for (i=0 ; i<size ; i++) {
c[i] = temp[i] ; // assign sorted string back to c
c[size] = '\0' ;
}
// puts(c) <- when puts() is run here, desired output is given
}
In this program, the function takes char a , concatenates it with char b, which is assigned to c.
char c is then sorted and printed out in the main function by puts(c).
For example,
Enter the first string:
afkm
Enter the second string:
bbbggg
abbbfgggkm
mergeStr():
This is the output i get when puts(c) is run from within void mergeStr() function.
However, puts(c) from int main() does not print anything.
This:
/* Merge string a and string b together, then sort them alphabetically */
c = strcat(a,b) ;
doesn't do what you seem to expect, it doesn't write into the caller's (i.e. main()'s) buffer at all. It overwrites the value of c (the function argument) with the return value of strcat(), which will be the destination, i.e. a.
You need to read up on how C strings work, and how the memory holding them is handled.
That particular call could be replaced by:
sprintf(c, "%s%s", a, b);
but this is dangerous and risks overwriting buffers since no size information is passed into the function (so it can't use snprintf()).

What happens if characters are assigned into int variables in C

I am trying to get a integer value from argv[1].
I want to know what happens if the user inputs a character so that I can avoid it. I tried '\0' and currently this doesn't work.
int main(int argc, char* argv[]){
int MAX_SIZE;
MAX_SIZE=atoi(argv[1]);
while(MAX_SIZE=='\0'){
printf("plz input in correct format: ");
scanf("%d", &MAX_SIZE);}
Any help would be appreciated.
Your code is a bit weird but from what I understand you want to check if a character is a number or not, for that you can use the function isdigit() to check if the entered value is a number or not, something like this:
char c='a';
if(isdigit(c)) //if true, i.e. it returns non-zero value
cout<<"number";
else // if false, i.e. it returns zero
cout<<"Char";
I have written C++ code as I am more comfortable in C++ but the function isdigit() works in both C and C++.
# include <stdio.h>
# include <stdlib.h>
int main ( int argc, char *argv[] )
{
int i, n, a;
printf("\n argv[0] = %s\n", argv[0] );
if ( argc <= 1 )
{
printf("\n");
printf(" argc = %d, no arguments given on command line\n", argc );
printf("\n");
}
for ( i = 1; i < argc; i++ )
{
n = sscanf( argv[i], "%d", &a );
if ( n == 1 )
{
printf(" read %d off command line in argv[%d]\n", a, i );
}
else
{
printf(" sscanf failed, n = %d, argv[%d] = %s\n", n, i, argv[i] );
}
}
return 0;
}

Is there a good way to say that if char array contains null then do something?

I've been trying to find a good way to find the end of a partially filled char array. What I've been trying is if array[x] != null, but that doesn't seem to be working.
If your char array is null terminated, checking for the first null should work. If it isn't, you're doing something wrong.
In practice, there needs to be a char that determines the end of your char array, otherwise it's impossible to tell where it ends, unless you consider the length of the array itself.
You could use strlen to achieve this.
#include <stdio.h>
#include <string.h> // strlen
int main (int argc, char** argv) {
char str_array[32];
strcpy (str_array, "I am short");
printf ("string length: %d\n", strlen(str_array));
printf ("last index: %d\n", str_array[strlen(str_array)]);
return 0;
}
This should return
string length: 10
last index: 0
Notice that strlen () returned the length of the string stored in the array which is also the index of the NULL ('\0') terminator.
#include <stdio.h>
int main (int argc, char **argv)
{
int i ;
char array[64] ;
for (i = 0; i < 64; ++i)
array[i] = 'a' ;
array[5] = '\0' ;
for (i = 0; i < 64; ++i)
{
if (array[i+1] == '\0')
break ;
}
printf ("the filled string ends after %d characters.\n", i-1) ;
return 0 ;
}
How about the following way?
int i=0
char array[30];
fillArray(&array); //some function that writes characters to this array
for(i=0;i<30;i++) {
if(array[i] == '\0') {
printf("Char array is a string\n");
break;
}
}

Beginner C, why is a bunch of random stuff added to my string?

I have the following program that I want to read in my name (Sahand) character by character and store in a string:
#include <stdio.h>
int main(int argc, const char * argv[]) {
char temp;
char str[6];
int i;
for ( i = 0 ; i < 6 ; i++ )
{
scanf(" %c",&temp);
printf("Our temp is: %c\n",temp);
str[i] = temp;
printf("Our total string is: %s\n",str);
}
printf("Program ended with the string: %s\n",str);
return 0;
}
The output is this:
s
Our temp is: s
Our total string is: s
a
Our temp is: a
Our total string is: sa
h
Our temp is: h
Our total string is: sah
a
Our temp is: a
Our total string is: saha
n
Our temp is: n
Our total string is: sahan
d
Our temp is: d
Our total string is: sahandd\350\367\277_\377
Program ended with the string: sahandd\350\367\277_\377
Program ended with exit code: 0
As you can see, everything is going fine until the final letter, d, is entered, when another d and a bunch of random stuff is added onto the string. Could someone explain to me what is happening here?
You should be adding the null character to the string before printing. Since you're printing inside a loop, add it to the next character. Just absolutely be sure that the for loop doesn't go beyond the bounds of the array.
#include <stdio.h>
int main(int argc, const char * argv[]) {
char temp;
char str[7];
int i;
for ( i = 0 ; i < 6 ; i++ )
{
scanf(" %c",&temp);
printf("Our temp is: %c\n",temp);
str[i] = temp;
str[i+1] = '\0';
printf("Our total string is: %s\n",str);
}
printf("Program ended with the string: %s\n",str);
return 0;
}
Another option is to actually initialize each character in the C-String to be the '\0' character (without ever overwriting the last one); As some others have mentioned in the comments, this can be accomplished in the declaration of the array as such:
char str[7] = { 0 };
You need null character('\0') to end your string(array) at the 5th index in order to tell the compiler that this is the end of string(in your case character array i.e., str). But you were using 5th index to store character 'd'.
The compiler is taking garbage value from the memory
In order to run your program correctly, you need to declare the str array as below:
char str[7];
And insert null character('\0') at (i+1)th position.Look below:
#include <stdio.h>
int main(int argc, const char * argv[]) {
char temp;
char str[7];
int i;
for ( i = 0 ; i < 6 ; i++ )
{
scanf(" %c",&temp);
printf("Our temp is: %c\n",temp);
str[i] = temp;
str[i+1] = '\0';
printf("Our total string is: %s\n",str);
}
printf("Program ended with the string: %s\n",str);
return 0;
}
After reading the comments, I changed the following line in my program:
char str[6];
to
char str[7];
That did the trick and the program executes as I wish.
EDIT:
In addition to changing this line, I added a str[6] = 0; after the variable declaration.

Using command line in C to detect arguments, and then print out the first or second char of the arguments

I need to make a program that accepts no less than 2 and no more than 6 arguments at the command line and then prints out the 1st or 2nd character
EX: asdf asdf asdf asdf
prints out as: a s a s
I have the initial array setup and working, the for loops below are meant to cut the string off at a space in the input and copy it to a new string, but it is not working correctly. I am new to C, and to this site. Any help is greatly appreciated.
#include <stdio.h>
#include <string.h>
int main(){
char a[50];
char b[50];
char c[50];
char d[50];
char e[50];
char f[50];
int i;
printf("enter a string (Ex: asdf asdf asdf... Must have atleast 2 arguments but no more than six): ");
scanf("%s", a);
printf("%c", a);
for (i = 0; i != 50; i++){
if(a[i]==' '){
char strncpy(b, &a[i], i+2);
printf("\n%c ",a[1]);
printf("%c ",b[0]);
}
}
for (i = 0; i != 50; i++){
if(b[i]==' '){
char strncpy(c, &b[i], i+2);
printf("%c ",c[1]);
}
}
for (i = 0; i != 50; i++){
if(c[i]==' '){
char strncpy(d, &c[i], i+2);
printf("%c ",d[0]);
}
}
for (i = 0; i != 50; i++){
if(d[i]==' '){
char strncpy(e, &d[i], i+2);
printf("%c ",e[1]);
}
}
for (i = 0; i != 50; i++){
if(e[i]==' '){
char strncpy(f, &e[i], i+2);
printf("%c ",f[0]);
}
}
return 0;
}
You don't need to copy your strings out of anywhere... Coming from the command line you'll have them sitting in argv:
int main( int argc, char **argv )
{
}
Where argc is the total number of arguments plus 1 (the first is the name that invoked your program), and argv is an array of pointers to each argument string. These have already been tokenised from the command-line.
So first you wanna test you have enough arguments. I like to explicitly make a new variable to remove the off-by-one confusion from comparisons:
int nparams = argc - 1;
if( nparams < 2 || nparams > 6 ) {
printf( "Wrong number of arguments\n" );
return -1;
}
Then you loop over your arguments. The first will be in position 1 of the array... From your example, it seems that you print the first character of the first argument, and the second character of the next, then continue alternating. That's a modulo operation. I have a variable which that chooses which character to print.
int i, which;
for( i = 1; i <= nparams; i++ ) {
which = (i-1) % 2;
printf( "%c\n", argv[i][which] );
}
This does assume that every second argument is at least two characters long. No error checking. If you need error checking, you need to make sure that the character you're printing is not the string-terminator (value 0). In the case of the second character, you also need to check the value before it is not 0. I don't know if it's possible to specify an argument that is a string of zero length. Perhaps a reader who does know can comment.
Well, I may as well put it in... So your loop would look a little like this:
if( argv[i][0] == 0 || argv[i][which] == 0 ) {
printf( "\n" );
} else {
printf( "%c\n", argv[i][which] );
}

Resources