Solved

String manipulation in C

Posted on 2016-09-25
12
48 Views
Last Modified: 2016-10-17
This program for returning the re-arranged string where taking the first letter of a “word” and appending that letter to the end of the word with “ay” added to the end as well.

Please help me to write the return function properly instead of printing them. Currently it works with Printf commands.


#include <stdio.h>
#include <string.h>
#include <ctype.h>

void Translate(const char* in, const char* out)
{
    static const char* SEP = " .,?";  // word separators

    // Iterate input by words
    const char *sep = NULL, *word = NULL, *end = in; *temp=out;
    while (sep = end,  // separators from previous word end
           word = &end[strspn(end, SEP)],  // start of word
           end = &word[strcspn(word, SEP)],  // end of word
           *sep)  // iterate until we hit terminating zero character
    {
        int wordlen = (int)(end - word);
        int seplen = (int)(word - sep);
        if (wordlen > 0 && isalpha(word[0]))  // word starts with a letter, pig it!
        {
            char firstletter = tolower(word[0]);
            const char* suffix = (firstletter == 'a') ? "y" : "ay";
            //printf("\n%s",&sep[seplen]);
            //printf("\n%s",&word[1]);
            printf("\n%.*s%.*s%c%s",
                seplen, sep,            // separators from previous word
                wordlen - 1, &word[1],  // word without first letter
                firstletter, suffix);
        }
        else  // not a real word, just print unchanged
        {
            printf("%.*s%.*s", seplen, sep, wordlen, word);
        }
    }
}

int main()
{
    char inputBuffer[100];
    char outputBuffer[200];
    printf("\n Enter the string: \n");
    fgets(inputBuffer, sizeof(inputBuffer), stdin);
    
    Translate(inputBuffer,outputBuffer);
}

Open in new window

0
Comment
Question by:Member_2_6613198
  • 3
  • 3
  • 3
  • +2
12 Comments
 
LVL 17

Expert Comment

by:Pawan Kumar Khowal
ID: 41815469
Can you post your input and output , Shall write the program for you !
0
 

Author Comment

by:Member_2_6613198
ID: 41815479
Example
Input = Darrin, what are you doing with 500 KG and 100 KG?
Output = arrinday, hatway reay ouyay oingday ithway 500 Gkay nday 100 Gkay?

Darrin, has become arrinday,
are become reay
0
 

Expert Comment

by:Muhammad Ahsan
ID: 41816101
try writing your output to txt file .

for example

char name;
    int  number;
    FILE *f;
    f = fopen("scambledtext.txt", "a");

 
    fprintf(f, "%c\n\n", output of program);
    fclose(f);



note; to add multiple output just  use fprint statement for every output before closing file
0
 
LVL 32

Expert Comment

by:sarabande
ID: 41816115
you should answer to phoffric's question as experts can only give little help in case of a homework question. if it is homework (or similar academical purpose) you should ask specific questions to your code rather than expect us to give a solution for the whole function.

for example, you could ask

Which argument types and return type should I choose for the Translate function

We then could answer like,

int Translate(const char * input, char * output, int sizOutput);

Open in new window


where you pass a zero-terminated string as input and provide a buffer for the output string with the size such that the function can avoid any buffer overflow. note, the output string may not be const since you can't write on it if so.

the return value is the output length on success. if the output is NULL, the return value is the required output length. if buffer size too small, the return code is error -1 .

Sara
0
 

Author Comment

by:Member_2_6613198
ID: 41817621
@phoffric: it's an assignment.  

Can you help me on this . I am trying to append the few characters(depends on seplen) from *sep(which is character pointer)

            for (i=0;i<seplen;i++)
            {
                temp[j]=*sep++;
               
            }

I am getting runtime error when I do like this. That's why I want people advise on posted code
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 45

Assisted Solution

by:Kdo
Kdo earned 250 total points (awarded by participants)
ID: 41817707
Hi Member,

I don't see the declaration for temp[] in your program, but I suspect that it's not large enough to contain the new string.  When you try to append characters to the string in temp[], the program is overwriting the next variable(s).

Make sure that temp[] is large enough to hold the entire string.

Kent
0
 

Author Comment

by:Member_2_6613198
ID: 41817726
This piece code complied properly but i dont see the output it's blank

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>

void piglatinize(const char* in)
{
    static const char* SEP = " .,?";  // word separators

    // Iterate input by words
    const char *sep = NULL, *word = NULL, *end = in;
    char *temp = (char*) malloc(1000*sizeof(char)+1);
    int i,j=0;
    while (sep = end,  // separators from previous word end
           word = &end[strspn(end, SEP)],  // start of word
           end = &word[strcspn(word, SEP)],  // end of word
           *sep)  // iterate until we hit terminating zero character
    {
        int wordlen = (int)(end - word);
        int seplen = (int)(word - sep);

        if (wordlen > 0 && isalpha(word[0]))  // word starts with a letter, pig it!
        {
            char firstletter = tolower(word[0]);
            const char* suffix = (firstletter == 'a') ? "y" : "ay";
            
            for (i=0;i<seplen;i++)
            {
                temp[j]=*sep++;
                
            }
            printf ( "\n%s",temp);
            /*printf("%.*s%.*s%c%s",
                seplen, sep,            // separators from previous word
                wordlen - 1, &word[1],  // word without first letter
                firstletter, suffix);*/
        }
        else  // not a real word, just print unchanged
        {
            printf("%.*s%.*s", seplen, sep, wordlen, word);
        }
        j++;

    }
}

int main()
{
    piglatinize("Darrin, what are ");
}

Open in new window

0
 
LVL 45

Assisted Solution

by:Kdo
Kdo earned 250 total points (awarded by participants)
ID: 41817824
Part of the problem seems to be that temp[] isn't fully built.  That code looks a bit messy.

I think you can make the entire function a lot cleaner if you'll try to do less work yourself and let the C functions do more of it.

For example, the program starts like this:

void piglatinize(const char* in)
{
    static const char* SEP = " .,?";  // word separators

    // Iterate input by words
    const char *sep = NULL, *word = NULL, *end = in;
    char *temp = (char*) malloc(1000*sizeof(char)+1);

If this was my assignment, I'd start it like this:

void piglatinize(const char* instring)
{
    static const char* SEP = " .,?";  // word separators
    char *temp = strdump (instring);
    char temp[1000];

    // Iterate input by words
    const char *sep = NULL, *word = NULL, *end = in;

The two big changes are to make temp a stack variable instead of a dynamic array, and to make a copy of the input string that you can use without changing the original string.

Then call strtok() to walk through variable *in* (the copy of the passed string).  It'll do all of the token (word) isolation for you.  It's now a simple task to piglatinize (is that a word) the token returned by strtok().


Kent
0
 
LVL 32

Accepted Solution

by:
sarabande earned 250 total points (awarded by participants)
ID: 41818296
char *temp = strdump (instring);
     char temp[1000];
the two variables must have different names, for example tempin and tempout.

also it is good practice to initialize a stack buffer.

 char tempout[1000] = { '\0' };   // makes all chars zero.

Open in new window


using strtok make the code shorter but adds some shortcomings:

as Kent already told, you need to have a writeable copy of the input string when using strtok. that is because strtok replaces separator characters by zero characters. that behavior may add some serious problems to your code if not handled properly.

also loops to fill the buffer could be spared by using strcat granted that your output buffer was initialized with Zeros and you fill it sequentially.

my recommendation is to parse the const input string rather than using strtok.

i would do the parsing two times. the first round is to (only) count the number of words. if this is known you can calculate the size of the output buffer and either (A) create the return buffer at the heap (using calloc to get it zeroed) or (B) check the given buffer and given buffer size whether it is big enough (and return with error if not).

for (B) the signature of the function is

int piglatinize(const char * szInput, char pszOutput[], int outputSize);

for (A) your function could have the following signature:

int piglatinize(const char * szInput, char * * ppszOutput);

the char ** is a pointer to a char * pointer and allows in c to return a new pointer to the caller. the int return would return the size of the output buffer or -1 if there is some error.

with this the caller would do like

int main()
 {
     char * pszOutput = NULL;
     int len = piglatinize("Darrin, what are ", & pszOutput); // here it passes the address of the pointer to get a new pointer returned
     if (len > 0 && pszOutput != NULL)
     {
           printf("\n%s", pszOutput);
           free(pszOutput);
      }
      return (len > 0)? 0 : -1;
 } 

Open in new window



for parsing the input string you could copy the input string and call strtok as srecommended by Kent.

if you want to avoid strtok you nevertheless shouldn't use your current code but code like the following.

int pos = 0;
int lpos = strlen(szInput);
int npos = lpos;
char * pstrBreak = NULL;
int wordcount = 0;
...


while ((pstrBreak = strpbrk(&szInput[pos], szSep)) != NULL)
{
       npos = (int)(pstrBreak - szInput);
       if (npos > pos)
       {
             wordcount++;
       }
       pos = npos+1;
}
if (pos < lpos)
{
     wordcount++;
}

Open in new window


now you could calulate the required buffer size for output. you need the input length since you want to use each character of the input and for each word two characters extra and 1 zero char for termination. allocate the buffer and assign the pointer to a char * tempory variable.

then we could do a second loop in order to fill the new buffer.

in the second round you would determine start and length of each "word" and would concatenate
the parts instead of counting the words.

initialize pos and npos again and use the same while.

while (...)
{
      ...
      if (npos > pos)
      {
           // copy but omit the first character
           strncat(pszOutput, &szInput[pos+1], npos - (pos+1));
           // use strncat to copy the first char
           ...
           // use strncat to copy the "ay"
           ...
       }
       // use strncat to copy the current separator from szInput[npos]
       ...
}
// use strncat to copy the rest of szInput to pszOutput.
...

Open in new window


note, the above code doesn't handle different suffices "y" and "ay". you would need to add this, for example by using a 'wordallsuffixlength' in the first loop instead of a 'wordcount'.

if all done, you would assign the pszOutput to *ppszOutput what would return the pointer to the caller. then return the allocated length of the output.

Sara
0
 
LVL 45

Assisted Solution

by:Kdo
Kdo earned 250 total points (awarded by participants)
ID: 41818339
And as Sara almost pointed out, strdump() should have been strdup()!

:D
0
 
LVL 32

Expert Comment

by:sarabande
ID: 41846308
the Asker got valid corrections for the posted code and good and detailed suggestions how to solve the task. Full solutions could not be given because it was an assignment. An equal split between the contributors seems to be appropriate.

Sara
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Have you thought about creating an iPhone application (app), but didn't even know where to get started? Here's how: ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Important pre-programming comments: I’ve never tri…
Summary: This tutorial covers some basics of pointer, pointer arithmetic and function pointer. What is a pointer: A pointer is a variable which holds an address. This address might be address of another variable/address of devices/address of fu…
The goal of this video is to provide viewers with basic examples to understand and use structures in the C programming language.
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use for-loops in the C programming language.

705 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now