Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
c代码中的错误_C - Fatal编程技术网

c代码中的错误

c代码中的错误,c,C,我有一个c代码,它给了我一个分段错误,这个错误意味着我不明白。代码如下: #include <stdio.h> #include <assert.h> #include <stdlib.h> #include <string.h> #define STREQUAL(a,b) (strcmp(a,b) == 0) /* State of the 54-card deck. This keeps a spare deck for copying

我有一个c代码,它给了我一个分段错误,这个错误意味着我不明白。代码如下:

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

#define STREQUAL(a,b) (strcmp(a,b) == 0)

/* State of the 54-card deck.  This keeps a spare deck for copying
   into.  It also has three spare slots *behind* the start of the
   deck: two so the deck can be moved backward if a joker is moved
   from the bottom to the top in the first step, and one so that the
   reference to the card before the first joker always points
   somewhere even when there's a joker on the top of the pack. */

typedef struct SolState_t {
    int a, b;
    int *deck, *spare;
    int deck1[57], deck2[57];
} SolState_t ;

SolState_t state;

int verbose = 0;
int lastout, cocount;


#define JOKER_STEP(var,ovar) \
    (((var != 53) ? \
      (source[var] = source[var +1], var++) : \
      (source--, ovar++, source[0] = source[1], var = 1)), \
     ((var == ovar)?(ovar--):0))

/* Cycle the state for "rounds" outputs, skipping jokers
   as usual.  "lastout" is the last output, which is never a joker.

   If "rounds" is zero though, cycle the state just once, even
   if the output card is a joker. "lastout" may or may not be set.
   This is only useful for key setup.

   Note that for performance reasons, this updates the coincidence
   statistics under all circumstances, so they need to be set to zero
   immediately before the large batch run. */

static void cycle_deck(
    int rounds
)
{
    int *source, *s, *sb, *d;
    int lo, hi;
    int nlo, nhi, nccut;
    int output;

    do {
        assert(state.a != state.b);
        assert(state.deck[state.a] == 53);
        assert(state.deck[state.b] == 53);
        source = state.deck;
        JOKER_STEP(state.a,state.b);
        JOKER_STEP(state.b,state.a);
        JOKER_STEP(state.b,state.a);
        source[state.a] = 53;
        source[state.b] = 53;
        if (state.a < state.b) {
            lo = state.a;
            hi = state.b + 1;
        } else {
            lo = state.b;
            hi = state.a + 1;
        }
        nlo = 54 - hi;
        nhi = 54 - lo;
            /* We do both the triple cut and the count cut as one
               copying step; this means handling four separate cases. */
        nccut = source[lo -1];
        s = source;
        if (lo == 0) {
                /* There's a joker on the top of the pack.  This can
                   only happen in one exact circumstance, but when it
                   does nccount is wrong.  So we handle it specially. */
            assert(state.a == 0);
            assert(state.b == 2);
            d = &state.spare[51];
            sb = &source[3];
            while(s < sb) {*d++ = *s++;}
            d = &state.spare[0];
            sb = &source[54];
            while(s < sb) {*d++ = *s++;}
            state.a = 51;
            state.b = 53;
        } else if (nccut <= nlo) {
                /* The second cut is before the first joker. */
            d = &state.spare[nhi - nccut];
            sb = &source[lo -1];
            while(s < sb) {*d++ = *s++;}
            state.spare[53] = *s++;
            d = &state.spare[nlo - nccut];
            sb = &source[hi];
            while(s < sb) {*d++ = *s++;}
            d = &state.spare[53 - nccut];
            sb = &source[nccut + hi]; /* ccut */
            while(s < sb) {*d++ = *s++;}
            d = &state.spare[0];
            sb = &source[54];
            while(s < sb) {*d++ = *s++;}
            state.a += nlo - nccut - lo;
            state.b += nlo - nccut - lo;
        } else if (nccut < nhi) {
                /* The second cut is between the two jokers */
            d = &state.spare[nhi - nccut];
            sb = &source[lo -1];
            while(s < sb) {*d++ = *s++;}
            state.spare[53] = *s++;
            d = &state.spare[53 - nccut + nlo];
            sb = &source[nccut - nlo + lo]; /* ccut */
            while(s < sb) {*d++ = *s++;}
            d = &state.spare[0];
            sb = &source[hi];
            while(s < sb) {*d++ = *s++;}
            d = &state.spare[53 - nccut];
            sb = &source[54];
            while(s < sb) {*d++ = *s++;}
            if (state.a < state.b) {
                state.a = 53 - nccut + nlo;
                state.b = nhi - nccut -1;
            } else {
                state.b = 53 - nccut + nlo;
                state.a = nhi - nccut -1;
            }
        } else {
                /* The second cut is after the last joker. */
            d = &state.spare[53 - nccut + nhi];
            sb = &source[nccut - nhi]; /* ccut */
            while(s < sb) {*d++ = *s++;}
            d = &state.spare[0];
            sb = &source[lo -1];
            while(s < sb) {*d++ = *s++;}
            state.spare[53] = *s++;
            d = &state.spare[53 - nccut + nlo];
            sb = &source[hi];
            while(s < sb) {*d++ = *s++;}
            d = &state.spare[53 - nccut];
            sb = &source[54];
            while(s < sb) {*d++ = *s++;}
            state.a += 53 - nccut + nlo - lo;
            state.b += 53 - nccut + nlo - lo;
        }
        source = state.deck;
        state.deck = state.spare;
        state.spare = source;
        output = state.deck[state.deck[0]];
        if (output >= 26) {
            if (output >= 52) {
                if (output > 52)
                    continue;
                output = 0;
            } else {
                output -= 26;
            }
        }
        cocount += (lastout == output);
        lastout = output;
        rounds--;
    } while (rounds > 0);
}

static void print_deck(
)
{
  int i;

  for (i = 0; i < 54; i++) {
    if (state.deck[i] < 53) {
      putchar(' ' + state.deck[i]);
    } else if (i == state.a) {
      putchar('U');
    } else {
      assert(i == state.b);
      putchar('V');
    }
  }
}

/* Key the deck with a passphrase. */

static void key_deck(
    char *key
)
{
    int i, kval, *tmp;

    state.deck = state.deck1 + 3;
    state.spare = state.deck2 + 3;
    for (i = 0; i < 52; i++) {
        state.deck[i] = i+1;
    }
    state.deck[state.a = 52] = 53;
    state.deck[state.b = 53] = 53;
    for (; *key != '\0'; key++) {
        if ( *key >= 'A' && *key <= 'Z' ) {
            cycle_deck(0); /* Special value '0' is only useful here... */
                /* And now perform a second count cut based on the key letter */
            kval = *key - 'A' + 1;
            for (i = 0; i < 53; i++)
                state.spare[i] = state.deck[(i + kval) % 53];
            state.spare[53] = state.deck[53];
            if (state.a != 53)
                state.a = (state.a + 53 - kval) % 53;
            if (state.b != 53)
                state.b = (state.b + 53 - kval) % 53;
            tmp = state.deck;
            state.deck = state.spare;
            state.spare = tmp;
        if (verbose) {
            print_deck();
            printf(" after %c\n", *key);
        }
        }
    }
    /* These are touched by the keying: fix them. */
    lastout = 100; cocount = 0;
}

/* Encrypt a single character. */

static char encrypt_char(
    char char_in
)
{
    char char_out;

    cycle_deck(1);
    char_out = 'A' + (char_in - 'A' + lastout) % 26;
    if (verbose) {
        print_deck();
        printf(" %c -> %c\n", char_in, char_out);
    }
    return char_out;
}


int main(
    int argc,
    char *argv[]
)
{
    char **av = argv, *tmp;
    int slow_mode = 0;
    long rounds;

    /* Skip the name of the program */
    av++; argc--;
    if (argc  < 2) {
      printf("Usage: [flags] key message|len\n");
    }
    while (argc > 2) {
      if (STREQUAL(*av, "-v")) {
    verbose = 1;
      } else if (STREQUAL(*av, "-s")) {
    slow_mode = 1;
      } else {
    printf ("Unrecognised flag: %s\n", *av);
    exit(-1);
      }
      av++; argc--;
    }
    key_deck(av[0]);
    rounds = strtol(av[1], &tmp, 0);
    if (*tmp != '\0') {
      /* It's not a number - so it's a string! */
      char *text = av[1];
      int i = 0;

      for (; *text != '\0'; text++) {
    if (*text >= 'A' && *text <= 'Z') {
      if (i > 0 && (i % 5) == 0)
        putchar(' ');
      putchar(encrypt_char(*text));
      i++;
    }
      }
      while ((i % 5) != 0) {
    putchar(encrypt_char('X'));
    i++;
      }
      putchar('\n');
    } else {
      /* Treat it as a sequence of 'A's. */
      int i;

      if (rounds <= 0) {
    printf("Rounds number must be greater than zero\n");
    exit(-1);
      }
      if (verbose || slow_mode) {
    for (i = 0; i < rounds; i++)
      encrypt_char('A');
      } else {
    cycle_deck(rounds);
      }
      printf("Coincidences: %d / %ld\n", cocount, rounds -1);
    }
    return 0;
}
#包括
#包括
#包括
#包括
#定义STREQUAL(a,b)(strcmp(a,b)==0)
/*54卡片组的状态。这就为复制保留了一个备用甲板
进入它也有三个备用插槽*在*开始的*后面
甲板:两个,因此如果小丑被移动,甲板可以向后移动
从下到上的第一步,一个让
参考第一张牌之前的笑话总是点
甚至当有一个小丑在包的顶部*/
typedef struct SolState\u t{
INTA,b;
内部*甲板,*备用;
int deck1[57],deck2[57];
}SolState_t;
独立状态;
int verbose=0;
int lastout,cocount;
#定义JOKER_步骤(变量、ovar)\
((变量!=53)\
(source[var]=source[var+1],var++):\
(source--,ovar++,source[0]=source[1],var=1))\
((var==ovar)?(ovar--):0)
/*循环“回合”输出的状态,跳过小丑
像往常一样。“lastout”是最后一个输出,这绝不是开玩笑。
如果“轮数”为零,则仅循环一次状态,甚至
如果输出卡是小丑。“lastout”可以设置,也可以不设置。
这仅对密钥设置有用。
请注意,出于性能原因,这将更新
所有情况下的统计数据,因此需要将其设置为零
在大批量运行之前*/
静态空隙循环(
整数轮
)
{
int*source,*s,*sb,*d;
罗,你好,;
国际非直瞄、nhi、nccut;
整数输出;
做{
断言(state.a!=state.b);
断言(state.deck[state.a]==53);
断言(state.deck[state.b]==53);
source=state.deck;
小丑步(状态a,状态b);
小丑步(b州、a州);
小丑步(b州、a州);
来源[国家a]=53;
来源[国家b]=53;
如果(状态a<状态b){
lo=状态a;
hi=状态b+1;
}否则{
lo=状态b;
hi=状态a+1;
}
nlo=54-hi;
nhi=54-lo;
/*我们同时做三次切割和计数切割
复制步骤;这意味着处理四个单独的案例*/
nccut=源[lo-1];
s=来源;
如果(lo==0){
/*包的顶部有一个小丑。这个可以
只发生在一个确切的情况下,但当它
nccount是错误的,所以我们专门处理*/
断言(state.a==0);
断言(state.b==2);
d=&state.spare[51];
sb=&来源[3];
而(s=52){
如果(输出>52)
持续
输出=0;
}否则{
输出-=26;
}
}
cocount+=(lastout==输出);
lastout=输出;
轮--;
}而(轮数>0);
}
静态空白打印组(
)
{
int i;
对于(i=0;i<54;i++){
if(状态甲板[i]<53){
putchar(''+状态甲板[i]);
}else if(i==state.a){
putchar('U');
}否则{
断言(i==state.b);
putchar('V');
}
}
}
/*在甲板上键入密码短语*/
静态空键甲板(
字符*键
)
{
int i,kval,*tmp;
state.deck=state.deck 1+3;
state.spare=state.deck2+3;
对于(i=0;i<52;i++){
状态.甲板[i]=i+1;
}
状态甲板[状态a=52]=53;
状态甲板[状态b=53]=53;
对于(;*键!='\0';键++){
如果(*键>='A'&&*键2){
如果(STREQUAL(*av,“-v”)){
详细=1;
}否则如果(STREQUAL(*av,“-s”)){
慢模式=1;
}否则{
printf(“无法识别的标志:%s\n”,*av);
出口(-1);
}
av++;argc--;
}
钥匙牌(av[0]);
轮数=strtol(av[1],&tmp,0);
如果(*tmp!='\0'){
/*它不是一个数字,所以它是一个字符串*/
char*text=av[1];
int i=0;
对于(;*text!='\0';text++){
如果(*text>='A'&&&*text 0&&(i%5)==0)
putchar(“”);
putchar(加密字符(*文本));
i++;
}
}
而((i%5)!=0){
putchar(encrypt_char('X'));
i++;
}
putchar('\n');
}否则{
/*将其视为“a”的序列*/
int i;
如果(轮数

编辑答案为响应您的编辑,请尝试使用GDB: 运行: gdb myapp.exe 然后发出“开始”命令,然后再执行“步骤”,直到找到问题所在。这将帮助您将问题范围缩小到一个特定的功能

我应该提到,为了获得调试时的完整信息,请使用“-g”开关(使用gcc)进行编译。GDB的完整教程可用

A表示内存访问冲突。这通常是在C中编程时取消引用或访问越界数组索引的结果


尝试使用单步执行程序并确定分段错误发生的位置。

是的,我讨厌这种情况。在您展示一些代码之前,我们可以考虑的唯一解决方案是以100美元/小时的价格聘请一名顾问在现场查看您的代码。是的,发布项目的整个代码肯定是过火了。您需要将问题隔离到一个相对较小的代码片段中。没有人会阅读所有这些内容来找出您的问题所在。对,因此您需要一个调试器。堆栈溢出很难替代适当的调试器。过于简单化,但一个查找错误的简单策略是:不断删除代码行,直到错误消失走开。你上次删除的那一行就是有错误的那一行。谢谢你,伙计。这真的很有帮助。我正在努力找到er