需要帮助来理解数组

时间:2016-12-09 12:12:17

标签: c arrays cs50

我在C中学习数组并且我无法弄清楚为什么以下不正确?

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

int main(void)
{
    string plaintext = get_string();

    int x = 5;
    long long N = strlen(plaintext);
    string a = plaintext;
    long long c = 0;
    int z = x;

    for(int i = 0; i < N + (N/x) ; i++)
    {

        if( i == x)
        {
            a[c] = 32;
            c++;
            z = (z + x);
            //printf("%c\n", a[c]);           
        }

        a[c] = plaintext[i];
        //printf("%c\n", a[c]); 
        c++;
    }

    printf("%s\n", a);
}

它意味着在每个x字符之后将空格插入到一串文本中...我知道它效率不高(我认为我需要一些叫做指针的东西)但是为什么它不是工作?我使用调试器完成了它,看起来我的原始字符串正在改变,但是为什么?

3 个答案:

答案 0 :(得分:1)

假设stringchar *,则texta指向相同的字符串。这解释了原始字符串更改的原因。你能做的是:

string a= malloc(N+1 + N/x +1);

这为新字符串分配空间,在每个x个字符后用空格复制原始字符串。当xN为奇数时,为终止空字符添加1,为安全“添加1。

答案 1 :(得分:0)

#include <bits/stdc++.h>
using namespace std;
#define freinput "input.txt","r",stdin
#define freoutput "output.txt","w",stdout
#define mp make_pair
#define fi first
#define sc second
#define ellapse printf("Time : %0.3lf\n",clock()*1.0/CLOCKS_PER_SEC);
typedef long long ll;
typedef unsigned long int uld;
typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int,int> pii;
string s;
string stringInsertion(int x,string neww){

    for(int i = 0;i<s.size();i++){
        if(i!=0 && i%x==0){
            neww=neww+' '+s[i];
        }
        else neww+=s[i];
    }
    return neww;
}
int main(){

    cin>>s;
    int x = 2;
    string neww="";
    cout<<stringInsertion(x,neww);
}

just set the x number.hope this help

答案 2 :(得分:0)

Okay, let's do something similar first: Print out the string with spaces. Use i to loop through the string. Every time i is evenly divisibly by x, we print a space before we print the character, but not at the beginning:

void print_spaced(const char *s, int x)
{
    int i;

    for (i = 0; s[i]; i++) {
        if (i && i % x == 0) putchar(' ');
        putchar(s[i]);
    }

    putchar('\n');
}

You don't need to determine the length beforehand, because you can stop when you hit the terminating null character. That is, keep going as long as s[i] is not null. (Recall that s[i] is the same as s[i] != '\0' and similarly, i is the same as i != 0.)

Now let's fill a char array with the spaced out string instead of printing it:

int space_out_unsafe(char *res, const char *s, int x)
{
    int i, k = 0;

    for (i = 0; s[i]; i++) {
        if (i && i % x == 0) res[k++] = ' ';
        res[k++] = s[i];
    }

    res[k] = '\0';
    return k;
}

This function takes an additional parameter: A char buffer to fill. It has a second index, k, which is the current length of the result buffer. Whenever we printed in the first version, we now append a character to the string:

res[k++] = '#';

Tis overwrites the current end and moves k on one position. We don't write a newline at the end, but we must null-terminate the result.

There is one problem, though: The buffer may overflow; note how I have labelled the function above unsafe. Arrays in C have a fixed size and won't grow automatically when something is appended. It is there fore a good idea to pass the maximum buffer size max to the function and check for overflow before appending:

int space_out(char *res, int max, const char *s, int x)
{
    int i, k = 0;

    for (i = 0; s[i]; i++) {
        if (i && i % x == 0 && k < max - 1) res[k++] = ' ';
        if (k < max - 1) res[k++] = s[i];
    }

    res[k] = '\0';
    return k;
}

You can now use this function like this:

char res[20];

space_out(res, sizeof(res), "Doremifasola", 2);
puts(res);

There are other ways to accomplish this. You could allocate the memory dynamically, as Paul suggested. That way, you can cater for the additional space you need, but you also make the caller of the function take care of cleaning up the allocated memory with free. Dynamically allocating memory is something to look into after your first week. :)

Another possibility is to space out the string in place, that modify the contents of the original buffer. You still have to take care to provide the extra space, though. (Usually, in-place midofication is used when the result string is shorter, e.g. when filtering out characters.) You should also process your string from the and as not to overwrite data you need later with spaces. If you feel confident, that's an exercise for next week, too.