Char array[?]

Hi,

This is class work so all I need is a little direction, s'il vous plait?
I have a teacher that DEMANDS we use char arrays, never strings, and I can't find any function that we've been introduced to or otherwise that will add onto the same char array.

I know it's a little messy, but my main problem is this; I'm supposed to turn words into symbols and back again. I found a way to do that, but I can't account for the spaces between words. A lab assistant suggested I read them in ONE AT A TIME? So...I would read the word, check if it was the right word and then pass it to the editing array with an added space. Alter it if necessary.
I can find no way to repeatedly ADD a char array to the end of another char array. Should I discard the null char on the end, add a ' ' then repeat somehow and it would work? Reading letter by letter is not like reading word by word..:<

There seem to be a lot of functions to slice and dice strings when they are DECLARED as a string, char arrays(letter by letter)...
Am I missing something obvious?
Advice would be appreciated.


<
#include <iostream>
#include <cctype>
#include <string.h>
#include <stdio.h>

using namespace std;
// shorthand or long text functions
void shorthand( char arr[], int length);
void ltext(char arry[], int length);



int main(){
// integer for choices, character for initial entered text, character for editing array, length for array length.
int var;
char text[200];
char edit[200];
int length;


do{
// prompt for user input options

cout << "\nWould you like to convert to (1)plain text or (2)shorthand notation or (3)quit " << endl;
cin >> var;
cin.ignore(100, '\n');


//read text
if (var == 1 || var == 2)
cout << "\nEnter text here: ";
cin.get(text, 200, '\n');
cin.ignore(100,'\n');


//makes separate array for editing
strcpy(edit, text);
//finds length of input array
length = strlen(text);


//function call
if (var == 1)
shorthand(edit, length);

//function call
if(var == 2)
ltext(edit, length);



}while(var != 3);

return 0;
}


//converts text to shorthand
void shorthand( char edit[], int length){


for (int i=0; i< length; i++){

while (edit[i] == 'a' && edit[i+1] == 'n' && edit[i+2] == 'd'){
edit[i] = ' '; edit[i+1]='+'; edit[i+2]= ' ';
}

while (edit[i] == 't' && edit[i+1] == 'h' && edit[i+2] == 'e'){
edit[i+1] = '-'; edit[i+2] = ' ';
}

while (edit[i] == 'i' && edit[i+1] == 'n' && edit[i+2] == 'g'){
edit[i] = ' '; edit[i+1] = '!';
}

while (edit[i] == 'i' && edit[i+1] == 's' && edit[i+2] == 'h'){
edit[i] = ' '; edit[i+1] = '!';
}
while (edit[i] == 'e' && edit[i+1] == 'd' ){
edit[i] = ' '; edit[i+1] = 't';
}

while (edit[i] == 'w' && edit[i+1] == 'i' && edit[i+2] == 't' && edit[i+3]== 'h'){
edit[i+1] = '/'; edit[i+2] = ' '; edit[i+3] = ' ';
}

while (edit[i] == 'i' && edit[i+1] == 's'){
edit[i] = ' '; edit[i+1] = '$';
}

}
for (int x=0; x< length; x++){
cout << edit[x];
}

}

//converts shorthand to text
void ltext( char edit[], int length){


for (int i=0; i< length+10; i++){

while (edit[i] == '+'){
edit[i] = 'a'; edit[i+1] = 'n'; edit[i+2] = 'd';
}

while (edit[i] == 't' && edit[i+1] == '-'){
edit[i] = 't'; edit[i+1] = 'h'; edit[i+2]= 'e';
}

while (edit[i] == '!' && edit[i+1] == 'g'){
edit[i] = 'i'; edit[i+1] = 'n'; edit[i+2]= 'g';
}

while (edit[i] == '!' && edit[i+1] == 'h') {
edit[i] = 'i'; edit[i+1] = 's'; edit[i+2] = 'h';
}
while (edit[i] == ' ' && edit[i+1] == 't' ){
edit[i] = 'e'; edit[i+1] = 'd';
}

while (edit[i] == 'w' && edit[i+1] == '/' ){
edit[i] = 'w'; edit[i+1]= 'i'; edit[i+2] = 't'; edit[i+3] = 'h';
}

while (edit[i] == '$') {
edit[i] = 'i'; edit[i+1] = 's';
}

}
for (int x=0; x< length; x++){
cout << edit[x];

}

}
>









strcat is a useful function.

char h[] = "hello";
char w[] = "world";
char result[100] = {0};

strcat(result, h);
strcat(result, " ");
strcat(result, w);

or, the beautiful function sprintf.

sprintf(result, "%s %s", h, w); //hello space world all together

Does this give you the tools you need?

sprintf is POWERFUL. It can convert numbers to text, hex - text, etc, perform concats, formatting, and more.

I did try strcat. I guess I'm just having trouble repeatedly reading into the same array for each word and overwriting it in the first array before passing each to the edit array. It's probably on me to make a for loop in the right spot.

Thanks for the response :)

> I have a teacher that DEMANDS we use char arrays, never strings

Your teacher is an idiot.

Something along these lines, perhaps:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include <iostream>
#include <cstring>

const char* const tokens[] =  { "and", "the", "ing", "ish", "with", /* etc */ } ;
const char* const symbols[] = { "&",   "-",   "!g",  "!h",  "w/", /* etc */ } ;

// sanity check
static_assert( sizeof(symbols) == sizeof(tokens), "#tokens-#symbols mismatch" );

constexpr std::size_t NTOKENS = sizeof(tokens) / sizeof( tokens[0] ) ;

// replace old_len characters at position pos in cstr with newstr
// invariant: pointers are not null, pos and old_len are within bounds
// invariant: the underlying sequence of bytes of cstr is large enough
char* replace( char* cstr, std::size_t pos, std::size_t old_len, const char* newstr )
{
    // http://en.cppreference.com/w/cpp/string/byte/strlen
    const auto cstrlen = std::strlen(cstr) ;
    const auto new_len = std::strlen(newstr) ;

    // move the tail right or left to adjust the space required for newstr,
    // copy characters from newstr into that space
    // http://en.cppreference.com/w/cpp/string/byte/memmove
    // http://en.cppreference.com/w/cpp/string/byte/memcpy
    const auto nchars = cstrlen-pos-old_len+1 ; // +1 to include the terminating null character
    if( old_len != new_len ) std::memmove( cstr+pos+new_len, cstr+pos+old_len, nchars ) ;
    std::memcpy( cstr+pos, newstr, new_len ) ;

    return cstr ;
}

// convert characters in cstr to
//     to short hand from long text if to_short == true
//     to long text from short hand if to_short == true
// invariant: pointer is not null
// invariant: cstr is large enough to hold the converted string
char* convert( char* cstr, bool to_short )
{
    // original == tokens, replacement == symbols if converting
    // from long text to short hand; vice versa otherwise
    const auto original = to_short ? tokens : symbols ;
    const auto replacement = to_short ? symbols : tokens ;

    for( std::size_t i = 0 ; i < NTOKENS ; ++i ) // for each original
    {
        // http://en.cppreference.com/w/cpp/string/byte/strstr
        const auto ptr = std::strstr( cstr, original[i] ) ;
        if( ptr != nullptr ) // if found
        {
            // replace with replacement
            replace( cstr, ptr-cstr, std::strlen( original[i] ), replacement[i] ) ;

            // continue looking for more originals
            return convert( cstr, to_short ) ;
        }
    }

    return cstr ; // no more originals were found; we are done
}

// convert long text to short hand
char* to_short_hand( char* cstr ) { return convert( cstr, true ) ; }

// convert short hand to long_text
char* to_long_text( char* cstr ) { return convert( cstr, false ) ; }

int main()
{
    char text[] = "with abc and def and the ghijing and with klmish and the nop with qrst and..." ;
    std::cout << text << '\n' ;
    std::cout << to_short_hand(text) << '\n' ;
    std::cout << to_long_text(text) << '\n' ;
}

http://coliru.stacked-crooked.com/a/18a9f6cc36df7e1c
overwriting the same array, just use strcpy

editing is a pain, if you need to insert or delete a character. memmove will do it for you, but it should be used "carefully".

inserting zero (the byte value 0) to end strings is critical to get correct if you start messing with the arrays directly in your own loops.

the functions I use 99% of the time for char arrays are a tiny subset..
strcat, strcyp, memmove, strstr, sprintf. I haven't had many tasks I could not do with only those. And pointers. If manipulating a large string that represents a whole document, you need a lot of pointers to track where you are, often a start / end of the section you are working on + a working pointer to process it + a temporary string.



Apparently we're not supposed to use constants either. I haven't used memcpy, auto or memmove before. I'm still a neophyte here ^^; I went through the lab and the book and I don't think she really went over even strcat yet. I didn't think sprintf could be used with c++ but it does sound useful.
Thanks for the alternative functions guys :)
Apparently we're not supposed to use constants either.

There is hopefully some administrative rationale (e.g., "it hasn't been taught yet") that explains that particular ban. If the teacher instead believes that constants are bad for some technical reason, I suggest you make a serious effort to take the class from someone who understands the topic they are trying to teach. That issue is fundamental enough to cast significant doubt upon the quality of the rest of the course.
Last edited on
With any luck, you will NEVER have to use memmove or memcpy. These functions are mostly obsolete in c++, only exception would be a weird/dated vanilla c++ (no stl, etc) embedded system.

sprintf is fine in c++, its in <cstdio> I think, a properly namespaced and c++ header file. Obsolete, of couse, but they are still part of the language.

Nothing I showed you is useful, it was 100% obsolete stuff. But it won't hurt you to see it, because there is nearly 50 years of code out there using it, you are bound to run into some of it now and then, and most c++ coders run into pure C now and then as well.





Last edited on
Topic archived. No new replies allowed.