I've missed a week of class in which they covered pointers but I haven't been able to get the notes from class but my HW is due and I still don't understand how to use pointers to pass strings from function to function... below is my code in which I realize the pointers are beyond messed up but I've tried to read other forums but just get lost. Any help is appreciated.
#include <stdio.h>
char* returnInPlace(char);
int palindrom(char, char );
main(void)
{
char newString[20];
printf("Enter a string: ");
scanf("%s",&newString);
char flippedString[20]=reverseInPlace(newString);
int palCheck= palindrome(newString, flippedString);
if (palCheck==0)
printf("\n\tThe reverse string is %s, so we don't have a palindrome.", flippedString);
else
printf("\n\tThe reverse string is %s, so we do have a palindrome.", flippedString);
}
char* reverseInPlace(char newString)
{
int iterator;
char flipped[20];
char *ptr1;
for(iterator=0;iterator<20;iterator++)
{
flipped[iterator]=firstString[19-iterator];
}
ptr1=flipped[];
return *ptr1;
}
int palindrome(char newString, char flippedString)
{
int iterator;
int palCheck=1;
for(iterator=0;iterator<20;iterator++)
{
if (firstString[iterator]==secondString[iterator])
continue;
else
{
palCheck=0;
break;
}
}
return palCheck;
}
Problem 1
In char* reverseInPlace(char newString), you're using
return *ptr1;
which is wrong. What you may want is
return ptr1;
Problem 2
ptr1=flipped[];
is wrong. Here, you're assigning the base address of a local variable flipped and returning that value. flipped will cease to exist after reverseInPlace() finishes execution. You need to use dynamic memory allocation.
Problem 3
char flippedString[20]=reverseInPlace(newString);
is wrong. You cannot assign an array with = unless as initialization at time of definition.
Problem 4
char* reverseInPlace(char newString)
this function definition looks wrong by seeing the way it is being called. Maybe what you want is
char* reverseInPlace(char* newString)
instead.
......and maybe many more. Strongly suggest to read some good book about Pointers and C basics before jumping into writing code.
Related
So I suck with functions and need to debug this. Im pretty sure the function ToPigLating does its job well at converting. However I just need help calling the function ToPigLatin inside of my main function. But when I try doing that I just get a bunch of error codes.
#include <stdlib.h>
#include <string.h>
#define LEN 32
char* ToPigLatin(char* word[LEN]){
char word[LEN];
char translation [LEN];
char temp [LEN];
int i, j;
while ((scanf ("%s", word)) != '\0') {
strcpy (translation, word);
//just pretend I have all the work to convert it in here.
} // while
}
int main(){
printf("Enter 5 words: ");
scanf("%s", word);
ToPigLatin();
}```
Roughly, variables only exist within the function they're declared in. The word in ToPigLatin exists only within ToPigLatin. It is not available in main. This lets us write functions without worrying about all the rest of the code.
You need to declare a different variable in main, it can also be called word, to store the input and then pass that into ToPigLatin.
Let's illustrate with something simpler, a function which doubles its input.
int times_two(int number) {
return number * 2;
}
We need to give times_two a number.
int main() {
// This is different from "number" in times_two.
int number = 42;
// We have to pass its value into time_two.
int doubled = times_two(number);
printf("%d doubled is %d\n", number, doubled);
}
Your case is a bit more complicated because you're working with input and memory allocation and arrays. I'd suggest just focusing on arrays and function calls for now. No scanf. No strcpy.
For example, here's a function to print an array of words.
#include <stdio.h>
// Arrays in C don't store their size, the size must be given.
void printWords(const char *words[], size_t num_words) {
for( int i = 0; i < num_words; i++ ) {
printf("word[%d] is %s.\n", i, words[i]);
}
}
int main(){
// This "words" variable is distinct from the one in printWords.
const char *words[] = {"up", "down", "left", "right"};
// It must be passed into printWords along with its size.
printWords(words, 4);
}
ToPigLatingToPigLating function expects to have a parameter like ToPigLating("MyParameter");
Hello there icecolddash.
First things first, there are some concepts missing. In main section:
scanf("%s", word);
You're probably trying to read a string format and store in word variable.
In this case, you should have it on your declaration scope. After some adjustment, it will look like this:
int main(){
char word[LEN];
As you defined LEN with 32 bytes maximum, your program will not be allowed to read bigger strings.
You're also using standard input and output funcitions as printf, and so you should ever include stdio.h, thats the header which cointains those prototypes already declared, avoiding 'implicit declaration' compiling warnings.
Next issue is how you're declaring your translation function, so we have to think about it:
char* ToPigLatin(char* word[LEN])
In this case, what you wrote:
ToPigLatin is a funcion that returns a char pointer, which means you want your function to probably return a string. If it makes sense to you, no problem at all. Although we got some real problem with the parameter char* word[LEN].
Declaring your variable like this, assume that you're passing an array of strings as a parameter. If I got it right, you want to read all five words in main section and translate each one of them.
In this case I suggest some changes in main function, for example :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LEN 32
#define MAX_WORDS 5
char *globalname = "translated";
char* ToPigLatin(char* word){
char *translation = NULL;
//Translation work here.
if ( !strcmp(word, "icecolddash") ){
return NULL;
}
translation = globalname;
return translation;
}
int main(){
char word[LEN];
char *translatedword;
int i;
printf("Enter 5 words: \n");
for ( i=0; i < MAX_WORDS; i++ ){
fgets(word, sizeof(word), stdin);
strtok(word, "\n"); // Just in case you're using a keyboard as input.
translatedword = ToPigLatin(word);
if ( translatedword != NULL ){
//Do something with your translation
//I'll just print it out as an example
printf("%s\n", translatedword);
continue;
}
// Generic couldn't translate message
printf("Sorry, I know nothing about %s\n", word);
}
return 0;
}
The above code translate every word in a fixed word "translated".
In case of reading the exact input "icecolddash", the program will output a generic error message, simulating some problem on translation process.
I hope this help you out with your studies.
There are a few things that I see.
#include <stdio.h>
#include <stdlib.h>
char* ToPigLatin(char* word){
printf(word);
return word;
}
int main(){
printf("Enter 5 words: ");
// declare the variable read into by scanf
char * word = NULL;
scanf("%s", word);
//Pass the variable into the function
ToPigLatin(word);
// Make sure you return an int from main()
return 0;
}
I left some comments in the code with some specific details.
However, the main thing that I would like to call out is the style of the way you're writing your code. Always try to write small, testable chunks and build your way up slowly. Try to get your code to compile. ALWAYS. If you can't run your code, you can't test it to figure out what you need to do.
As for the char ** comment you left on lewis's post, here is some reading you may find useful in building up your intuition:
https://www.tutorialspoint.com/what-does-dereferencing-a-pointer-mean-in-c-cplusplus
Happy coding!
So, I'm brand spanking new to C. C# does garbage collection for me, so i don't need to worry about this stuff usually. This is causing me a days worth of problems, and I'm not finding any real example code where passing references and pointers as arguments is clearly exlained.
I also understand that passing things by value is considered poor practice, but I can't even grasp the concept of passing and referencing things in the first place.
Stated Goal: set value of a type defined string in another function, without a typed function, or any return values.
Any elementary explanation of passing pointers and references functionally would be helpful. The "Programming in C" book says to do something like this:
swap(int *a, int *b){
//swap
}
//main
int a, b;
swap(&a,&b);
And if it could be done using some semblance of my code sample?
Thanks so much in advance!
Code:
#include <stdio.h>
//yes I'm aware that I need to set the array size
//to be larger than string length + 1 to account for "\0"
//this is a contrived, overly simplistic example for the sake
// of hopefully getting a very clear basic example
typedef char * string;
void func2(string *str){
str = "blah"
//currently, my code here does not change the value of str
//as declared in main
//have tried multiple different formats
//i.e. func2(&str)
//func2(str)
//func2(*str)
//etc
//*str in this context I thought should be a pointer to the value of str passed from func
//or perhaps str should be... not exactly sure what is going on and why
//this is so difficult
}
void func(string *str){
str = "blah blah";
//also trying
//*str = "blah"
//under the impression that this is now a char *** type? or char ** type?
//in my code, str may be passed to a func2(str);
//where it may be manipulated again
//it is my understanding that passing func2(&str) would
//pass in the address of a pointer, which I don't want
//or passing func2(*str) would pass a pointer to a pointer
// which i also don't want.
}
main(){
string str;
//pass location of str in memory
funct(&str);
//this code will print the str set in func, but not when modified in func2
printf("%s", str);
}
Making minimal modifications to your code, you might want something like this:
#include <stdio.h>
typedef char * string;
void func2(string *str){
*str = "blah";
}
void func1(string *str){
func2(str);
}
int main(){
string str;
func1(&str);
puts(str);
func2(&str);
puts(str);
return 0;
}
Compiled and tested okay.
I'm trying to write a function that takes in two strings, concatenates them, and then writes them to a 2D array. I have been messing around with different things and looking at other posts to no avail. The seg fault seems to occur in the last strcpy when I'm trying to write the the concatenated string to the char array. If that line is commented out the program seems to work just fine.
void saveToArray(char *command1, char *command2)
{
char *saveCommands[30][100];
int *commands = malloc(sizeof(int));
char concatCommand[30];
strcpy(concatCommand, command1);
strcat(concatCommand, " ");
strcat(concatCommand, command2);
strcpy(*&saveCommands[0][*commands], concatCommand);
*commands += 1;
}
I apologize in advance for any formatting issues as this is my first post and thanks for any answers!
There are a number of scary things going on in this function. For starters...
int *commands = malloc(sizeof(int));
You don't free this or return it, so it is 100% a memory leak. I see no reason why you should want to allocate this integer on the heap rather than the stack.
char concatCommand[30];
strcpy(concatCommand, command1);
strcat(concatCommand, " ");
strcat(concatCommand, command2);
This could potentially overflow your buffer.
strcpy(*&saveCommands[0][*commands], concatCommand);
*& is a no-op (it doesn't do anything). You don't copy anything into commands, so *commands could be anything. Finally, the pointers in saveCommands aren't initialized so strcpy(saveCommands[x][y], "some string") will basically always segfault in practice. I think you might want this instead:
char saveCommands[30][100]
...
strcpy(&saveCommands[0][*commands], concatCommand);
I took the liberty to re-write your code a bit... too many characters make my eyes hurt... at any rate, this code works. It was mainly the strcpy dereference that was causing the issue.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void cmds(char *c1, char *c2) {
char sc[30][100];
int c = 0;
char cc[30];
strcpy(cc, c1);
strcat(cc, " ");
strcat(cc, c2);
strcpy(&sc[c][0], cc); // problem was here...
printf("%s\n", &sc[c][0]);
}
int main() {
char *c1 = "c001";
char *c2 = "c002";
cmds(c1, c2);
return 0;
}
Hi I really can't get my head around this. I'm basically trying to return a char array from a function by passing the output array in as a parameter. Here is what I have so far:
The function:
int GetComputerName(char *name, char *ip_address){
*name = "testing";
return 0;
}
And calling it:
char comp_name[50];
GetComputerName(&comp_name, serverIP);
printf("\n\n name: %s\n\n", comp_name);
I have tried switching and swapping the * and & to see what will work and have read up on pointers and stuff yet what I think should be happening an what actually does happen is two very different things and now I think I have confused myself more than when I started!! lol
Can someone please help me out and explain what the correct way of doing this is?!
Thanks in advance =)
This line:
*name = "testing";
is invalid, as you assign the pointer to "testing" into a char pointed by name. You need to copy the data into the buffer. It should be:
int GetComputerName(char *name, char *ip_address){
strcpy(name,"testing");
return 0;
}
or even better (to avoid overflows):
int GetComputerName(char *name, size_t buff_len, char *ip_address){
strncpy(name,"testing", buff_len);
name[buff_len - 1] = '\0';
return 0;
}
And call it:
GetComputerName(comp_name, sizeof(comp_name), serverIP);
I make this program ::
#include<stdio.h>
char *raw_input(char *msg);
main() {
char *s;
*s = *raw_input("Message Here Is: ");
printf("Return Done..");
printf(s);
}
char *raw_input(char *msg){
char *d;
printf("%s", msg);
scanf("%s",&d);
return d;
}
What this do is, it print my message and scan for input from the user, then print it,, but whats the problem in print the input from the user ???
Update::
I need the raw_input func. call be like this without any extra
*s = *raw_input("Message Here");
I dont want to use this ::
raw_input("Message Here Is: ", d);
....
Just want to return the string that the user will enter .
Update2::
from jamesdlin Answer( Thank You ),,Now its clear to my that's my problem was in how to return an allocated string in this :)
#include<stdio.h>
#define buffer 128
char *raw_input(char *msg);
main() {
char *s;
s = raw_input("Message Here Is: ");
printf("%s\n",s);
}
char *raw_input(char *msg){
char *d;
printf("%s", msg);
fflush(stdout);
fgets(d, buffer, stdin); ## In this there is a problem
return d;
}
now when i start this program its print the message and then just exit(end)the program without taking any word from the user ???
You don't allocate memory for d, so using it in scanf leads to undefined behaviour.
Actually, it's even worse than that: you pass the address of d to scanf, which is then filled with the integer read from console. In effect, you initialize a pointer with an integer value, so the pointer points to somewhere out in the jungle. Thus dereferencing it is undefined behaviour. [Update]: even this is not all: as #Heath pointed out below, this in fact allows you to corrupt your call stack by entering a sufficiently long input on the console :-((( [/Update]
Not to mention that you are trying to return a local variable from your function, which is destroyed as soon as it gets out of scope. This should work better:
void raw_input(char *msg, char *d);
main() {
char d[128];
raw_input("Message Here Is: ", d);
printf("Return Done..");
printf(d);
}
void raw_input(char *msg, char *d){
printf("%s", msg);
scanf("%s", d);
}
Fair enough, this does not prevent buffer overflow... but it is enough to ilustrate my point.
Update: so you want to return an allocated string (i.e. a char* pointer) from raw_input() in any case. AFAIK you have 3 choices:
return a pointer passed in by the caller as a parameter (a slight extension of my example above): this is the one I would prefer. However, this requires an extra function parameter (in fact 2, since we should also pass in the length of the buffer in a proper solution to avoid buffer overflows). So if you absolutely need to stick to the function signature shown above, this isn't an option.
return a pointer to a static / global buffer visible to both caller and callee: this is a variation of the above, to avoid modifying the function signature. The downside is that the code is more difficult to understand and maintain - you don't know that the function modifies a static / global variable without actually looking at its implementation. This in turn also makes unit testing more difficult.
return a pointer to a buffer allocated inside the function - although technically possible, this is the worst option, since you effectively pass on the ownership of the buffer; in other words, the caller must remember to free the buffer returned. In a simple program like the one you showed above, this may not seem like a big issue, but in a big program, that buffer may be passed around to far away places within the app, so there is a high risk that noone frees it in the end, thus leaking memory.
The pointer d in the function is uninitialized. scanf would be filling up arbitrary memory. Instead, you need to pass a buffer (character array) for it to fill, and the buffer has to be defined in main, otherwise it'll be destroyed before you can return it (unless you do dynamic allocation, but that's another story).
#include<stdio.h>
char *raw_input(char *msg);
int main() {
char *s;
s = raw_input("Message Here Is: ");
printf("Return Done..");
printf("%s", s);
free(s);
return 0;
}
char *raw_input(char *msg){
char *d;
d = malloc(20)
if(d==0) return 0;
printf("%s", msg);
scanf("%19s", d);
return d;
}
Try this, should work. The other answers pointed your errors out, as I can see... I was to slow ;)
EDIT: Ok, found an error... fixed it ;)
EDIT2:
Max suggested a struct was possible, here is some code:
#include<stdio.h>
struct mystring{
char str[20];
};
struct mystring raw_input(char *msg);
int main() {
struct mystring input;
input = raw_input("Message Here Is: ");
printf("Return Done..");
printf("%s", input.str);
return 0;
}
struct mystring raw_input(char *msg){
struct mystring input;
printf("%s", msg);
scanf("%19s", input.str);
return input;
}
As mentioned, you aren't allocating memory for use with scanf. But never ever use scanf; it's hard to use correctly and to avoid buffer overflows. Use fgets.
From the comp.lang.c FAQ: Why does everyone say not to use scanf? What should I use instead?
Also, while unrelated to your problem, this bit of code is dangerous:
*s = *raw_input("Message Here Is: ");
printf("Return Done..");
printf(s);
You are passing user-input directly to printf as a format strings, so this is susceptible to format string attacks if the printed string happens to include % characters. Better:
*s = *raw_input("Message Here Is: ");
printf("Return Done..");
printf("%s\n", s);
Also, you might want some newlines when you print. Also:
*s = *raw_input("Message Here Is: ");
won't work because s doesn't point to anything, so you're dereferencing a garbage pointer. Assuming that you fix raw_input to return an allocated string, it should be:
s = raw_input("Message Here Is: ");
Lastly (also unrelated to your problem):
char *raw_input(char *msg){
char *d;
printf("%s", msg);
scanf("%s",&d);
return d;
}
You should call fflush(stdout) after printing the prompt. See My program's prompts and intermediate output don't always show up on the screen, especially when I pipe the output through another program.
Try this experiment:
#include<stdio.h>
char *raw_input(char *msg);
main() {
char *s;
s = raw_input("Message Here Is: ");
printf("Return Done..");
printf(s);
}
char *raw_input(char *msg)
{
int value = 0;
char *d;
printf("%s", msg);
scanf("%s",&d);
if (value)
printf("value has become %08X\n", value);
return d;
}
Perform several experiements with input messages as long as: 3, 4, 5, 7, 8, 9, 11, 12, 13, etc. characters long. See what the result is for the integer variable value. You will see that due to your misuse of scanf() by passing the address of d, you are allowing scanf() to destroy local variables of your function, including the return address.
And that gets us back to the name of this web site.
You can not return a pointer of a variable that has been created inside the function. The variable d is not valid anymore in the main function.
try this:
1. create the variable d in the main function
2. and pass it to the raw_input function
void raw_input(char *msg, char *d)