Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
#include<stdio.h>
#include<stdlib.h>
char *syllable[26] = {"a","bub","cash","dud","e","fud","gug","hash","i","jay",
"kuck","lul","mum","nun","o","pub","quack","rug","sus",
"tut","u","vuv","wack","xux","yuck","zug"};
void Tutnese(char *word, char *newword);
char *letter;
void Tutnese(char *word, char *newword)
{
//clrscr();
for(*letter = 'A'; *letter <= 'Z'; *letter++)
{
letter=syllable;
printf("%c\n",&letter);
}
}
Tutnese is an English language game primarily used by children who use it to converse in
(perceived) privacy from adults (or vice versa)
I am trying to let A="A" B="bub" c="cash" and so on.
I am expecting a result like this.
“computer.” becomes “cashomumpubututerug.”
- “Stony” become “Sustutonunyuck”
but i just start learning c, and i have no idea how to use pointer. I've been keep getting error like assignment makes integer from pointer without a cast
char *letter;
This statement declares a variable named letter, same way as any other statement like char ch; will do.
Now, what's the difference then!!
Well the difference (and similarity) is:
char ch; declares a char variable, i.e. a memory block of size 1 byte is allocated (statically), which you can refer to using ch.
char *letter; on the other hand declares a char pointer i.e. a memory size of 2 or 4 or 8 bytes (depending on compiler) will be allocated (again statically) to store address of a char variable.
Now when you use *letter as lvalue (on Left Hand Side) as you do in for loop, this means you are trying to write to the memory address stored in letter. In your case you never stored any address in letter, to do so you can use letter = &ch; where ch is some char variable.
That was all the lecture!!
Now my suggestion for your program:
You don't need to use letter pointer for the loop, a simple char i variable will be fine.
To re-form the string as you plan to, you can simply use the characters of the original string as indices to form new string. Declare a empty string of some large length, then keep concatenating the syllable[orig_string[i] - 'A'], inside a for loop till the end of orig_string. Assumption is orig_string contains all uppercase alphabets
Finally, Correct your printf syntax.
Do read about pointers in C from a good source, as they will never leave you, and will give you all sorts of nightmare.
Code
#include <ctype.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *syllable[26] = {"a","bub","cash","dud","e","fud","gug","hash","i","jay",
"kuck","lul","mum","nun","o","pub","quack","rug","sus",
"tut","u","vuv","wack","xux","yuck","zug"};
void Tutnese(char *word, char *newword, size_t new_size);
void Tutnese(char *word, char *newword, size_t new_size)
{
char *end = newword + new_size;
char c;
while ((c = *word++) != '\0')
{
if (!isalpha(c))
*newword++ = c;
else
{
char *tut = syllable[tolower(c) - 'a'];
ptrdiff_t len = strlen(tut);
if (end - newword <= len)
break;
memcpy(newword, tut, len + 1);
newword += len;
}
}
*newword = '\0';
}
int main(void)
{
char i_data[1024];
char o_data[4096];
while (fgets(i_data, sizeof(i_data), stdin) != 0)
{
Tutnese(i_data, o_data, sizeof(o_data));
printf("I: %sO: %s", i_data, o_data);
}
return(0);
}
Output
I: computer
O: cashomumpubututerug
I: how do you tell mum that she cannot understand us?
O: hashowack dudo yuckou tutelullul mumumum tuthashatut sushashe cashanunnunotut ununduderugsustutanundud usus?
I: The quick brown fox jumped over the lazy dog.
O: tuthashe quackuicashkuck bubrugowacknun fudoxux jayumumpubedud ovuverug tuthashe lulazugyuck dudogug.
Lets forget about pointers and break down the problem.
You're given a word word and you want to create newword based on your mapping.
First, you need to figure out how big newword is.
To do that, iterate through the characters in word and add the string lengths of the mappings (call it N)
Once you've done that, you know you can allocate N+1 bytes (strings are null terminated in C) for newword (via malloc).
Then, you iterate through the characters again and just append to newword
Let me give you a few hints:
To iterate through a string (lets call it word), the C code would look like:
unsigned int wordlen = strlen(word);
for(unsigned int index = 0; index < wordlen; index++)
printf("Character at %u is %c", index, word[index]);
Your for loop is quite messed up. Do look up a few tutorials on pointers and string manipulation in C.
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
Let the array I have declared be:
char input[] = {'a','l','d'};
Now, I have to insert another character inside this array. Can I insert my character inside this array, or do I have to change the size of the input array and then insert?
Do char input[] = {'a','l','d'} and char input[3]={'a','l','d'} both have the same meaning, or in the first case is the size of array not fixed?
What do I have to do if I want to replace all characters in my array with '3', '.', '1', '4'?
char input[] = {'a','l','d'} and char input[3]={'a','l','d'} do both have same meaning
Yes, they have the same meaning.
now I have to insert an another character inside this array
I have to change the size of the input array
It is not possible to change the size of an array or to insert elements into it. The size of an array remains constant through the lifetime of the array.
can u please tell me what to do to insert new character in the same array
You don't, because you can't.
In C++, I would recommend using the std::string class to represent a character string that can change size. A minimal example:
std::string input = "ald";
input.push_back('i');
If you have
char input[] = {'a','l','d'};
then the array is of size exactly 3, and there's no possibility to store additional characters in it.
You can overwrite:
input[1] = 'n';
but that replaces a character, not insert.
If you declare the array with some extra size, then you have some wiggle room.
char input[10] = {'a','l','d', '\0'};
Now we have room for 10 characters, and null termination to make it a proper string, so we can easily print it:
printf("input = %s\n", input);
This prints "input = ald".
Overwrite a character:
input[1] = 'n';
printf("input = %s\n", input);
This prints "input = and".
Add a character at the end:
input[3] = 'y';
input[4] = '\0'; /* since we just overwrote the old one */
printf("input = %s\n", input);
This prints "input = andy".
Slide some characters to the right, to make room for new ones
for(int i = 4; i >= 2; i--) /* move two characters, and \0, to the right */
input[i+1] = input[i];
input[2] = 'o';
printf("input = %s\n", input);
This prints "input = anody".
Another way to move characters is with memmove:
memmove(&input[4], &input[2], 4); /* move three characters, and \0, two to the right */
input[2] = 'y';
input[3] = 'b';
printf("input = %s\n", input);
This prints "input = anybody".
But this is all very fussy and error-prone. Examples like I've shown can teach you how characters, arrays, and strings work in C, but they're hard to get right, and I wouldn't necessarily recommend that you write code like this to manipulate your own strings.
If you want to replace all characters, it's easy enough, as long as you're sure there's room. Just use strcpy:
strcpy(input, "3.14");
printf("input = %s\n", input);
This prints "input = 3.14".
You have to be careful when calling strcpy, though. The destination array has to be (a) writable and (b) big enough. If you wrote
char input2[3];
strcpy(input2, "3.14"); /* WRONG */
that would be wrong, because input2 is not big enough. And if you wrote
char *input3 = "hello";
strcpy(input3, "3.14"); /* WRONG */
that would be wrong, because input3 is now a pointer, that points to an unnamed array containing the string "hello", and while it's big enough, it's probably an unwritable constant string.
#include <stdio.h>
char strA[80] = "A string to be used for demonstration purposes";
char strB[80];
char *my_strcpy(char *destination, char *source)
{
char *p = destination;
while (*source != '\0')
{
*p++ = *source++;
}
*p = '\0';
return destination;
}
int main(void)
{
my_strcpy(strB, strA);
puts(strB);
}
so my question here is that when i take out the portion:
//*p= '\0';
it prints the exact same answer, so why is this necessary? from my understanding, \0 is a nul portion of memory after a string but since the array strA already contains the nul portion since its in "" is it really necessary?
It seems you already know the importance of the null terminator, but the point is, you defined char strB[80]; in external namespace (with static life span), which causes initialization of the array strB, which sets all bytes of it to zero. That's why you can't observe the difference (because even if you don't append a null character, the rest of strB already is).
Moving the definition of strB makes this visible. strA doesn't need moving because it doesn't matter.
In actuality, this code
while (*source != '\0')
{
*p++ = *source++;
}
// *p = '\0';
When *source reaches a null character, it's not copied to *p, so you need to manualky add a terminator for that.
Your loop stops when it sees the \0 and so it is not copied to the destination and the destination is not NUL terminated. Is that a problem?
Not if your destination buffer is initialized to all 0s
Not if your code is willing to deal with fixed length strings (so the my_strcpy signature would need to change to return the length)
In general YES - the 0 terminated C string is such a common thing that not following the convention is asking for trouble,
Whether you 0 terminate or not the rest of the values will be the same as they were when you started. The 0 termination just makes your character array a "standard C string".
For arguments sake: Assuming you knew every string had space for 80 chars you could just do
for(int i = 0; i < 80; i++)
{
dest[i] = src[i];
}
The effect is the same and assuming the source is 0 terminated the destination will be too.
This question already has answers here:
C++ Reverse Array
(5 answers)
Closed 7 years ago.
This is an amateur question. I searched for other posts about this topic, found lots of results, but am yet to understand the concepts behind the solution.
This is a practice problem in my C++ book. It is not assigned homework. [Instructions here][1] .
WHAT I WOULD LIKE TO DO:
string input;
getline(cin, input); //Get the user's input.
int front = 0;
int rear;
rear = input.size();
WHAT THE PROBLEM WANTS ME TO DO
string input;
getline(cin, input); //Get the user's input.
int* front = 0;
int* rear;
rear = input.size();
Error: a value of type "size_t" cannot be assigned to an entity of type int*
This makes sense to me, as you cannot assign an 'address' of an int to the value of an int.
So my questions are:
What is the correct way to go about this? Should I just forget about initializing front* or rear* to ints? Just avoid that all together? If so, what would be the syntax of that solution?
Why would this problem want me to use pointers like this? It's clear this is a horrible usage of pointers. Without pointers I could complete this problem in like 30 seconds. It's just really frustrating.
I don't really see an advantage to EVER using pointers aside from doing something like returning an array by using pointers.
Thanks guys. I know you like to help users that help themselves so I did some research about this first. I'm just really irritated with the concept of pointers right now vs. just using the actual variable itself.
Posts about this topic that I've previously read:
[Example 1][2]
[Example 2][3]
[Example 3][4]
[1]: http://i.imgur.com/wlufckg.png "Instructions"
[2]: How does reversing a string with pointers works "Post 1"
[3]: Reverse string with pointers? "Post 2"
[4]: Reverse char string with pointers "Post 3"
string.size() does not return a pointer - it returns size_t.
To revert a string try this instead:
string original = "someText"; // The original string
string reversed = original; // This to make sure that the reversed string has same size as the original string
size_t x = original.size(); // Get the size of the original string
for (size_t i = 0; i < x; i++) // Loop to copy from end of original to start of reversed
{
reversed[i]=original[x-1-i];
}
If you really (for some strange reason) needs pointers try this:
string input;
getline(cin, input); //Get the user's input.
char* front = &input[0];
char* rear = &input[input.size()-1];
but I would not use pointers into a string. No need for it.
I guest you may not quite understand the problem here. This problem want you to COPY a C string then REVERSE it by pointer operation. There is no classes in standard C. So, the C string is quite different from string class in C++. It is actually an array of char-type elements ended with character '\0'.
After understand this, you may start to understand the problem here. If you want to copy a C string, you can not just use str_a = str_b. You need constructor here. However, in pure C style, you should REQUIRE memory space for the string at first (you can use malloc here), then copy each element. For example, you want to create a function to make a copy of input string,
#include <string.h>
char *strcopy(char* str_in) {
int len = strlen(str_in);
char *str_out = (char*)malloc(len+1);
char *in = str_in;
char *out = str_out;
while(*in != '\0') { *out++ = *in++; }
return str_out;
}
As you see, we actually use char* not int* here to operate string element. You should distinguish the pointer (such as in) and the element pointed by the pointer (such as *in) at first.
I'll show you a solution in pure C style for your problem, I hope this would help you to understand it. (You should be able to compile it without modification)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* strreverse(char* in){
// length of input string
int len = strlen(in);
// allocate memory for string operation
char *out = (char*)malloc(len+1);
// initialize <front> and <end>
char *front = out, *end = out + len - 1;
char buffer;
// copy input string
for(int i = 0; i <= len; i++){ out[i] = in[i]; }
// reverse string
for(; front < end; front++, end--) {
buffer = *front;
*front = *end;
*end = buffer;
}
return out;
}
int main() {
printf("REVERSE >> %s\n", strreverse("Hello, World!"));
return 0;
}
This is not you would do by C++ in actual programming, however, I guess the problem here is trying to let you understand mechanism of pointers. In this aspect, original C style would help a lot.
This question already has answers here:
Why can't I write to a string literal while I *can* write to a string object?
(4 answers)
Closed 8 years ago.
Someone can tell me different between this code:
char *s1 ="Con Chim Non";
and this one:
char *s=new char[100];
gets(s);
Then, I add the word: "Con Chim Non".
After, I build a code that change value of the pointer. In first code, I got a problem about the address. The second is right. And this is my code:
void Strlwr(char *s)
{
if (s == NULL )
return ;
for (int i = 0; s[i] != '\0'; ++i)
{
if ( s[i] <= 'Z' && s[i] >= 'A')
s[i] = s[i]+32;
}
}
And someone can tell me why the first is wrong.
The first example:
char *s1 ="Con Chim Non";
You declare a pointer to a text literal, which is constant. Text literals cannot be modified.
The proper syntax is:
char const * s1 = "Con Chim Non";
Note the const.
In your second example, you are declaring, reserving memory for 100 characters in dynamic memory:
char *s=new char[100];
gets(s);
You are then getting an unknown amount of characters from the input and placing them into the array.
Since you are programming in the C++ language, you should refrain from this kind of text handling and use the safer std::string data type.
For example, the gets function will read an unknown amount of characters from the console into an array. If you declare an array of 4 characters and type in 10, you will have a buffer overflow, which is very bad.
The std::string class will expand as necessary to contain the content. It will also manage memory reallocation.
Currently I'm writing a rather extensive homework assignment that - among other things - reads a file, builds a binary search tree and outputs it.
Somewhere inside all that I've written a recursive method to output the values of the binary search tree in order.
void output(node* n)
{
if(n->leftChild != NULL)
output(n->leftChild);
cout << n->keyAndValue << " || ";
outputString += n->keyAndValue << '|';
if(n->rightChild != NULL)
output(n->rightChild);
}
No problem with that, but you'll notice the line outputString += n->keyAndValue << '|';, because I also want to have all the values inside a char array (I am not allowed to use strings or other more current features of C++) that I can use later on in a different method (e.g. Main method).
The Char-Array is declared as follows:
char *outputString;
This being just one of the ways I've tried. I also tried using the const keyword and just regularly building an array char outputString[]. With the version I've shown you I encounter an error when - later on in the program in a different method - calling the following code:
cout << outputString;
I get the following error:
Unhandled exception at 0x008c2c2a in BST.exe: 0xC00000005: Access Violation reading location 0x5000000000.
Any clue as to how I'd be able to build a dynamic char array, assign values to it numerous times using += and outputting it without triggering an access violation? I am sorry for asking a rather basic question but I am entirely new to C++.
Thanks and Regards,
Dennis
I'm guessing that since you can't use std::string, you also can't use new[].
You can concatenate strings with a function like this:
char *concat(const char *s1, const char *s2)
{
size_t len = strlen(s1) + strlen(s2);
char *result = (char*)malloc(len+1);
strcpy(result, s1);
strcat(result, s2);
return result;
}
This can be done more efficiently, but that probably doesn't matter for homework. And you need to check for errors, etc. etc.
You also need to decide who is going to call free on s1 and s2.
For what it is worth, the efficient version looks like this:
char *concat(const char *s1, const char *s2)
{
size_t len1 = strlen(s1);
size_t len2 = strlen(s2);
char *result = (char*)malloc(len1+len2+1);
memcpy(result, s1, len1);
memcpy(result+len1, s2, len2);
result[len1+len2] = '\0';
return result;
}
It's more efficient because it only walks the input strings once.
+= on pointers does pointer arithmetic, not string concatenation. Eventually you get way beyond your array that outputString was pointing to, and trying to print it leads to a segfault.
Since you can't use std::string, you need to use strcat along with new[] and delete[] and make sure you allocated your original array with new[].