#include <string.h>
void foo (char *bar)
{
char c[12];
strcpy(c, bar);
}
int main (int argc, char **argv)
{
foo(argv[1]);
return(1);
}
There are two problems :
if the program has no argument argv[1] is NULL and in foo you do strcpy(c, NULL); having an undefined behavior (typically a crash).
if the firs argument of the program has at least 12 characters strcpy(c, bar); will write out of c, again with an undefined behavior.
I do not speak about the fact the strcpy is in the best case useless because c is not used after
A secure version of your program with the minimal changes is :
#include <string.h>
void foo (char *bar)
{
char c[12];
strncpy(c, bar, sizeof(c) - 1);
c[sizeof(c) - 1] = 0;
}
int main (int argc, char **argv)
{
if (argc >= 2)
foo(argv[1]);
return(1);
}
Related
Summary
I am trying to pass the text that user has put in the terminal and pass it to the function named printString(). I don't fully understand C but I think I has to do with the pointer not being in the heap. Any help would be appreacitaed!
#include <stdio.h>
void printString();
int main (int argc, char* argv[]) {
int commandAmount = 1;
while (commandAmount < argc) {
printString(commandAmount, &argv);
}
return 0;
}
void printString(int commandAmount, char* argv[]) {
printf("the word is %s," , argv[commandAmount]);
}
./shortExample example
Segmentation fault (core dumped)
The prototype void printString(); does not match the actual implementation.
It should have been:
void printString(int commandAmount, char* argv[]);
You could also skip the prototype and just implement the function before main. Your loop while (commandAmount < argc) seems to not have any way to finish since you never increase commandAmount. This can cause undefined behavior and with such, your program may crash or do just about anything.
I suggest making a for-loop to fix that.
Example:
#include <stdio.h>
void printString(int commandAmount, char* argv[]) {
printf("the word is %s,", argv[commandAmount]);
}
int main(int argc, char* argv[]) {
for(int commandAmount = 1; commandAmount < argc; ++commandAmount) {
printString(commandAmount, argv);
}
}
or in the way you structured it:
#include <stdio.h>
void printString(int commandAmount, char* argv[]); // corrected
int main(int argc, char* argv[]) {
int commandAmount = 1;
while (commandAmount < argc) {
printString(commandAmount, argv);
++commandAmount; // needed
}
}
void printString(int commandAmount, char* argv[]) {
printf("the word is %s,", argv[commandAmount]);
}
For starters this function declaration
void printString();
does not provide a function prototype. So the compiler determines the type of the parameters of the function from the function call
printString(commandAmount, &argv);
However the expression &argv used in this call
printString(commandAmount, &argv);
has the type char *** due to the declaration of the identifier argv
int main (int argc, char* argv[]) {
^^^^^^^^^^^^
But the corresponding parameter in the definition of the function printString has the type char ** due to adjusting by the compiler parameters having array types to pointers to array element type.
That is this function declaration
void printString(int commandAmount, char* argv[]) {
is adjusted by the compiler to
void printString(int commandAmount, char** argv) {
^^^^^^^^^^^
Thus there are incompatible types of the argument expression and of the parameter. As a result this call
printf("the word is %s," , argv[commandAmount]);
invokes undefined behavior.
Moreover this loop in main
int commandAmount = 1;
while (commandAmount < argc) {
printString(commandAmount, &argv);
}
in general is an infinite loop because the variable commandAmount is not changed within the loop.
Firstly you should provide the function prototype before main to make your program more safer
void printString(int commandAmount, char** argv);
and call the function like
printString(commandAmount, argv);
^^^^
Of course you need also to change the loop in main.
Pay attention to that as the value of the parameter commandAmount is not outputted within the function then in fact it is redundant. You could pass to the function the pointer to the string itself. For example
#include <stdio.h>
void printString( const char *s );
int main( int argc, char* argv[] )
{
for ( int commandAmount = 1; commandAmount < argc; commandAmount++ )
{
printString( argv[commandAmount] );
}
putchar( '\n' );
return 0;
}
void printString( const char *s )
{
printf( "the word is %s, " , s );
}
#include <string.h>
void foo (char *bar)
{
char c[12];
strcpy(c, bar); // no bounds checking
}
int main (int argc, char **argv)
{
foo(argv[1]);
return 0;
}
Another ACTUAL option:
void foo (char *bar)
{
char c[12];
snprintf(c, sizeof c, "%s", bar);
}
The functions strncpy do not ensure the resulting strings are terminated by a NULL character and therefore you can have a bad resulting string.
Check whether the length of the bar is less than length of c.
code:
#include <string.h>
void foo (char *bar)
{
char c[12];
if ( strlen( bar ) < sizeof c ) {
printf("avoiding buffer overflow");
strcpy( c, bar );
}
}
int main (int argc, char **argv)
{
foo(argv[1]);
return 0;
}
I made it safe. Otherwise it's doing just the same thing as your original app, that is: nothing.
int main (int argc, char **argv)
{
return 0;
}
I'm new to C and I'm having a hard time understanding how to call methods with pointers. Currently this code should reverse a null-terminated string, but I get the errors
main.c:8:12: error: use of undeclared identifier 'sas'
char* N = sas;
^ main.c:10:10: warning: incompatible integer to pointer conversion passing 'char' to parameter of type
'char *'; remove * [-Wint-conversion]
reverse(*N);
^~ ./header.h:3:27: note: passing argument to parameter 'N' here EXTERN void reverse(char *N);
My actual code is this:
Main:
#include <stdio.h>
#include <stdlib.h>
#include "header.h"
int main(int argc, char *argv[])
{
char* N = sas;
reverse(*N);
}
reverse:
#include <stdio.h>
#include "header.h
#include <stdlib.h>
void reverse(char *str)
{
char* end = str;
char temp;
printf("this is *str: %c\n", *str);
if (str)
{
while (*end)
{
++end:
}
end--;
while (str < end)
{
temp = *str
*str++ = *end;
*end-- = temp;
}
}
}
header.h:
#define EXTERN extern
EXTERN void reverse(char *N)
thanks for the help and time!
int main(int argc, char *argv[])
{
char* N = "sas";
reverse(*N);
}
First you make N point to a string constant. Then you try to reverse what N points to. But since N points to a string constant, you're trying to reverse a string constant. By definition, constants cannot have their values changed.
First of all, there're many syntax errors within that piece of code:
'sas' what is that? your compiler thinks it's a variable but can't find any with that name. if you wanted to put a "sas" string, then:
char* N = "sas";
inconsistant brackets. More closing brackets than opening ones, and no opening bracket after declaring your function.
As I understand it, you are trying to reverse a string. This is just a slight modification of your code.
Full Source:
#include <stdio.h>
#include <stdlib.h>
void reverse(char *N);
int main(int argc, char *argv[])
{
char strSas[] = "sas";
reverse(strSas);
}
void reverse(char *str)
{
char* end = str;
char temp;
if(str) {
printf("this is *str: %c\n", *str);
while(*end) {
++end;
}
end--;
while(str < end) {
temp = *str;
*str = *end;
*end = temp;
++str;
--end;
}
}
}
My task is to compare some words and to find a character which is not used in both of them. Here is my code. But I'm getting a warning:
[Warning] passing argument 1 of 'ret' makes pointer from integer without a cast [enabled by default].
And when I'm trying to run it it says consolepauser.exe stopped working
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
char ret(char a[1][10],char b[3][10])
{
int i,j,p,t;
for (i=0;i<1;i++)
for (j=0;j<10;j++)
for (p=0;p<3;p++)
for (t=0;t<10;t++)
{
if (tolower(a[i][j]==tolower(b[p][t])))
{
p=3;
break;
}
if (p==2)
if (t==9) return tolower(a[i][j]) ;
}
return 'N';
}
int main(int argc, char *argv[]) {
char k[3][10]={"cHaOs","TOP","blAa"};
char b[1][10]={"SomeThIng"};
char q[1][10]={"HaPa"};
if (ret(b[1][10],k[3][10])='N') printf("No character") ;
else printf("%c",ret(b[1][10],k[3][10])) ;
return 0;
}
You should pass the parameters as:
if (ret(b, k) == 'N') printf("No character");
else printf("%c", ret(b, k));
[Warning] passing argument 1 of 'ret' makes pointer from integer without a cast
b[1][10] is a char, not a variable of type char [1][10], you should call ret() like this: ret(b, k). Others are similar.
Note: the valid indexes of char b[1][10]; are b[0][0], b[0][1], ..., b[0][9], the indexes in `b[1][10]1 are out-of-bounds, and will cause undefined behavior.
Here is a syntax fixed version of your code, you may want to compare it with your original code to find out other problems in it:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
char ret(char a[1][10],char b[3][10])
{
int i,j,p,t,e,r;
for (i=0;i<1;i++)
for (j=0;j<10;j++)
for (p=0;p<3;p++)
for (t=0;t<10;t++)
{
if (tolower(a[i][j])==tolower(b[p][t]))
{
p=3;
break;
}
if (p==2)
if (t==9) return tolower(a[i][j]) ;
}
return 'N';
}
int main(int argc, char *argv[]) {
int i,j,p,t,e,r;
char a,h;
char k[3][10]={"cHaOs","TOP","blAa"};
char b[1][10]={"SomeThIng"};
char q[1][10]={"HaPa"};
if (ret(b,k)=='N') printf("No character");
else printf("%c",ret(b,k));
return 0;
}
How to print the environment variables in a C program using environ.
extern char **environ
#include <unistd.h>
#include <stdio.h>
extern char **environ;
//...
int i = 0;
while(environ[i]) {
printf("%s\n", environ[i++]); // prints in form of "variable=value"
}
Do you mean
int main(int argc, char **argv, char **envp)
{
while(*envp!=null) {
printf("%s\n", *envp);
envp++;
}
return 0;
}